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/。以防万一,在使用它们之前先在那里尝试您的表达式。你永远不知道 ;)

虽然您手头有一个工作代码,但还有其他两种可能性,即 DomDocumentSimpleXML。这对于冒号(又名名称空间)有些棘手,但请考虑以下示例。我已经添加了一个容器标签来定义命名空间,但您肯定也会在 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