PHP: совпадение preg() неверно


У меня есть следующая строка:

<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>

И я пытаюсь проанализировать значение "w:sz w:val" с помощью preg_match().

До сих пор я пытался:

preg_match('/<w:sz w:val="(\d)"/', $p, $fonts);

Но это не сработало, и я не уверен, почему?

Есть идеи?

Заранее благодарю вас!

Author: Jan, 2015-11-12

3 answers

Вы пытались записать только однозначные числа. Попробуйте добавить +, чтобы сделать "один или несколько".

preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);

Я предпочитаю [0-9]+ для облегчения чтения, а также потому, что это позволяет избежать потенциально забавной необходимости удвоения символов \.

preg_match('/<w:sz w:val="([0-9]+)"/', $p, $fonts);
 4
Author: starlocke, 2015-11-12 19:32:24

Хотя у вас под рукой есть рабочий код, есть две другие возможности, а именно с 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: Использование SimpleXML с пространствами имен

$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
 3
Author: Jan, 2015-11-13 07:32:38

Вам просто нужно немного исправить ваше регулярное выражение:

<w:sz w:val="(\d)+"

Итак, получается:

preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);

Почему? Потому что только с помощью \d вы проверяете 1 цифру, но с помощью \d+ вы проверяете 1 или более.

РЕДАКТИРОВАТЬ:

На случай, если вам это понадобится, есть несколько отличных инструментов онлайн-тестирования регулярных выражений, таких как https://regex101.com /. Попробуйте свои выражения там, прежде чем использовать их, на всякий случай. Никогда не знаешь;)

 2
Author: Ignacio Téllez, 2015-11-12 19:38:47