2015-11-12 3 views
2

У меня есть следующая строка:PHP: preg_match() не правильно

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

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

Любые идеи?

Спасибо заранее!

+0

Почему нет: http://php.net/manual/en/book.simplexml.php? – AbraCadaver

+0

@AbraCadaver Я немного посмотрел на это.Вы знаете какие-либо другие библиотеки или пакеты PHP, которые конвертируют docx xml в html? – jldavis76

+0

Никогда не использовал его, но вот он: https://github.com/PHPOffice/PHPWord – AbraCadaver

ответ

4

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

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

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

preg_match('/<w:sz w:val="([0-9]+)"/', $p, $fonts); 
+0

Ты, сэр, потрясающий. Это была проблема. Спасибо. – jldavis76

2

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

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

Так он идет:

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

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

EDIT:

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

+2

Символ + должен, вероятно, войти в группу захвата() ... – starlocke

+0

О, извините. Ты прав! Я исправлю это сразу. –

3

Хотя у вас есть рабочий код, есть еще две возможности, а именно: DomDocument и SimpleXML. Это несколько сложно с двоеточиями (aka namespaces), но рассмотрим следующие примеры. Я добавил тег контейнера, чтобы определить пространство имен, но вы обязательно найдете его в своем 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 с Namespaces

$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 
+0

Это определенно выглядит интересно. Когда я попробую второе решение, я получаю сообщение об ошибке: Сообщение: пытается получить свойство не-объекта. Любая идея почему? – jldavis76

+0

@ jldavis76 Вы можете использовать 'var_dump ($ items);', чтобы увидеть, найдены ли элементы в первую очередь. Помните, что это работает только с ** моим ** xml в тот момент, когда я создал пространство имен. Очевидно, вам придется использовать свои собственные. – Jan

+0

Я предполагаю, что я немного незнакома с использованием пространств имен в этом аспекте. Я должен буду изучить его больше. Благодарю. – jldavis76

Смежные вопросы