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);
Но это не сработало, и я не уверен, почему?
Есть идеи?
Заранее благодарю вас!
3 answers
Вы пытались записать только однозначные числа. Попробуйте добавить +, чтобы сделать "один или несколько".
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
Я предпочитаю [0-9]+ для облегчения чтения, а также потому, что это позволяет избежать потенциально забавной необходимости удвоения символов \.
preg_match('/<w:sz w:val="([0-9]+)"/', $p, $fonts);
Хотя у вас под рукой есть рабочий код, есть две другие возможности, а именно с 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
Вам просто нужно немного исправить ваше регулярное выражение:
<w:sz w:val="(\d)+"
Итак, получается:
preg_match('/<w:sz w:val="(\d+)"/', $p, $fonts);
Почему? Потому что только с помощью \d вы проверяете 1 цифру, но с помощью \d+ вы проверяете 1 или более.
РЕДАКТИРОВАТЬ:
На случай, если вам это понадобится, есть несколько отличных инструментов онлайн-тестирования регулярных выражений, таких как https://regex101.com /. Попробуйте свои выражения там, прежде чем использовать их, на всякий случай. Никогда не знаешь;)