PHP: preg_match() 不正确
PHP: preg_match() not correct
我有以下字符串:
<w:pPr>
<w:spacing w:line="240" w:lineRule="exact"/>
<w:ind w:left="1890" w:firstLine="360"/>
<w:rPr>
<w:b/>
<w:color w:val="00000A"/>
<w:sz w:val="24"/>
</w:rPr>
</w:pPr>
我正在尝试使用 preg_match() 解析 "w:sz w:val" 值。
到目前为止,我已经尝试过:
preg_match('/<w:sz w:val="(\d)"/', $p, $fonts);
但这没有奏效,我不确定为什么?
有什么想法吗?
提前致谢!
您试图仅捕获个位数。尝试添加一个 + 使 "one or more".
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
我更喜欢 [0-9]+ 以便于阅读,并且因为它避免了可能有趣的需要加倍使用 \ 符号。
preg_match('/<w:sz w:val="([0-9]+)"/', $p, $fonts);
您只需要对您的正则表达式进行一点修正:
<w:sz w:val="(\d)+"
事情是这样的:
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
为什么?因为只有 \d 你要检查 1 个数字,但是 \d+ 你要检查 1 个或更多。
编辑:
如果您需要,可以使用一些很棒的正则表达式在线测试工具,例如 https://regex101.com/。以防万一,在使用它们之前先在那里尝试您的表达式。你永远不知道 ;)
虽然您手头有一个工作代码,但还有其他两种可能性,即 DomDocument
和 SimpleXML
。这对于冒号(又名名称空间)有些棘手,但请考虑以下示例。我已经添加了一个容器标签来定义命名空间,但您肯定也会在 xml 中有一个。
解决方案 1(DOM
方式)搜索带有命名空间前缀的 DOM 并读取属性。解决方案 2(SimpleXML
)做同样的事情(也许以更直观和易于理解的方式)。
XML:(使用PHP HEREDOC语法)
$xml = <<<EOF
<?xml version="1.0"?>
<container xmlns:w="http://example">
<w:pPr>
<w:spacing w:line="240" w:lineRule="exact"/>
<w:ind w:left="1890" w:firstLine="360"/>
<w:rPr>
<w:b/>
<w:color w:val="00000A"/>
<w:sz w:val="24"/>
</w:rPr>
</w:pPr>
</container>
EOF;
解决方案 1: 使用 DomDocument
$dom = new DOMDocument();
$dom->loadXML($xml);
$ns = 'http://example';
$data = $dom->getElementsByTagNameNS($ns, 'sz')->item(0);
$attr = $data->getAttribute('w:val');
echo $attr; // 24
解决方案 2:使用带有命名空间的简单XML
$simplexml = simplexml_load_string($xml);
$namespaces = $simplexml->getNamespaces(true);
$items = $simplexml->children($namespaces['w']);
$val = $items->pPr->rPr->sz["val"]->__toString();
echo "val: $val"; // val: 24
我有以下字符串:
<w:pPr>
<w:spacing w:line="240" w:lineRule="exact"/>
<w:ind w:left="1890" w:firstLine="360"/>
<w:rPr>
<w:b/>
<w:color w:val="00000A"/>
<w:sz w:val="24"/>
</w:rPr>
</w:pPr>
我正在尝试使用 preg_match() 解析 "w:sz w:val" 值。
到目前为止,我已经尝试过:
preg_match('/<w:sz w:val="(\d)"/', $p, $fonts);
但这没有奏效,我不确定为什么?
有什么想法吗?
提前致谢!
您试图仅捕获个位数。尝试添加一个 + 使 "one or more".
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
我更喜欢 [0-9]+ 以便于阅读,并且因为它避免了可能有趣的需要加倍使用 \ 符号。
preg_match('/<w:sz w:val="([0-9]+)"/', $p, $fonts);
您只需要对您的正则表达式进行一点修正:
<w:sz w:val="(\d)+"
事情是这样的:
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
为什么?因为只有 \d 你要检查 1 个数字,但是 \d+ 你要检查 1 个或更多。
编辑:
如果您需要,可以使用一些很棒的正则表达式在线测试工具,例如 https://regex101.com/。以防万一,在使用它们之前先在那里尝试您的表达式。你永远不知道 ;)
虽然您手头有一个工作代码,但还有其他两种可能性,即 DomDocument
和 SimpleXML
。这对于冒号(又名名称空间)有些棘手,但请考虑以下示例。我已经添加了一个容器标签来定义命名空间,但您肯定也会在 xml 中有一个。
解决方案 1(DOM
方式)搜索带有命名空间前缀的 DOM 并读取属性。解决方案 2(SimpleXML
)做同样的事情(也许以更直观和易于理解的方式)。
XML:(使用PHP HEREDOC语法)
$xml = <<<EOF
<?xml version="1.0"?>
<container xmlns:w="http://example">
<w:pPr>
<w:spacing w:line="240" w:lineRule="exact"/>
<w:ind w:left="1890" w:firstLine="360"/>
<w:rPr>
<w:b/>
<w:color w:val="00000A"/>
<w:sz w:val="24"/>
</w:rPr>
</w:pPr>
</container>
EOF;
解决方案 1: 使用 DomDocument
$dom = new DOMDocument();
$dom->loadXML($xml);
$ns = 'http://example';
$data = $dom->getElementsByTagNameNS($ns, 'sz')->item(0);
$attr = $data->getAttribute('w:val');
echo $attr; // 24
解决方案 2:使用带有命名空间的简单XML
$simplexml = simplexml_load_string($xml);
$namespaces = $simplexml->getNamespaces(true);
$items = $simplexml->children($namespaces['w']);
$val = $items->pPr->rPr->sz["val"]->__toString();
echo "val: $val"; // val: 24