PHP preg_match_all вопрос - PullRequest
       7

PHP preg_match_all вопрос

1 голос
/ 19 мая 2011

У меня вопрос по поводу обычной функции, которая доставляет мне горе. У меня есть список предметов, которые разделены в тегах. Я пытаюсь извлечь все между двумя конкретными тегами (которые встречаются несколько раз). Вот пример списка, который я анализирую:


<ResumeResultItem_V3>
    <ResumeTitle>Johnson</ResumeTitle>
    <RecentEmployer>University of Phoenix</RecentEmployer>
    <RecentJobTitle>Advisor</RecentJobTitle>
    <RecentPay>40000</RecentPay>
</ResumeResultItem_V3>

<ResumeResultItem_V3>
    <ResumeTitle>ResumeforJake</ResumeTitle>
    <RecentEmployer>APEX</RecentEmployer>
    <RecentJobTitle>Consultant</RecentJobTitle>
    <RecentPay>66000</RecentPay>
</ResumeResultItem_V3>


Я пытаюсь получить все между "ResumeResultItem_V3" в виде сгустка текста, но, похоже, я не могу правильно понять выражение.

Вот код, который у меня есть:




$test = "(<ResumeResultItem_V3>)";
$test2 = "(<\/ResumeResultItem_V3>)";

preg_match_all("/" . $test . "(\w+)" . $test2 . "/", $xml, $matches);

foreach ($matches[0] as $match) {
       echo $match;
       echo "<br /><br />";
}

Как я могу это исправить?

Ответы [ 4 ]

2 голосов
/ 19 мая 2011

Я делаю предположения о вашей структуре XML, но я действительно думаю, что вам нужен пример с использованием синтаксического анализатора XML, например SimpleXML .

$xml = new SimpleXMLElement( $file );
foreach( $xml->ResumeResultItem_V3 as $ResumeResultItem_V3 )
    echo (string)$ResumeResultItem_V3;
1 голос
/ 19 мая 2011

Если вы можете использовать выходные данные в виде массива с 1 элементом для каждого из совпадений «текстового объекта», попробуйте следующее:

<?php
$text =
"<ResumeResultItem_V3>
    <ResumeTitle>Johnson</ResumeTitle>
    <RecentEmployer>University of Phoenix</RecentEmployer>
    <RecentJobTitle>Advisor</RecentJobTitle>
    <RecentPay>40000</RecentPay>
</ResumeResultItem_V3>

<ResumeResultItem_V3>
    <ResumeTitle>ResumeforJake</ResumeTitle>
    <RecentEmployer>APEX</RecentEmployer>
    <RecentJobTitle>Consultant</RecentJobTitle>
    <RecentPay>66000</RecentPay>
</ResumeResultItem_V3>";

$matches = preg_split("/<\/ResumeResultItem_V3>/",preg_replace("/<ResumeResultItem_V3>/","",$text));
print_r($matches);
?>

Результат:

Array
(
    [0] => 
    <ResumeTitle>Johnson</ResumeTitle>
    <RecentEmployer>University of Phoenix</RecentEmployer>
    <RecentJobTitle>Advisor</RecentJobTitle>
    <RecentPay>40000</RecentPay>

    [1] => 


    <ResumeTitle>ResumeforJake</ResumeTitle>
    <RecentEmployer>APEX</RecentEmployer>
    <RecentJobTitle>Consultant</RecentJobTitle>
    <RecentPay>66000</RecentPay>

    [2] => 
)
1 голос
/ 19 мая 2011

Возможно, вам лучше использовать simplexml для извлечения данных здесь.

Но также ответить на вопрос регулярных выражений. \w+ соответствует только словам-символам. Но в этом случае вы хотите, чтобы он соответствовал практически всем, что находится между разделителями, для которых можно использовать .*?.

preg_match_all("/$test(.*?)$test2/s", $xml, $matches);

Работает только с модификатором /s.

1 голос
/ 19 мая 2011

Игнорируя, что вам , вероятно, следует использовать синтаксический анализатор XML , и что PHP имеет тот, который вы можете использовать ...

Проблема в том, что \w+соответствует символам слова, а не любому символу.Пробел и большинство знаков препинания не являются символами слов, поэтому совпадение не выполняется.Вместо этого вам нужно сопоставить «любому» символу . столько же, сколько существует +, но, поскольку вы, возможно, сможете чрезмерно группировать, вам нужен модификатор, чтобы сделать его не жадным, ?.Ваше выражение должно работать, если вы измените \w+ на .+? - для совпадения любого символа также требуется модификатор s, поэтому:

preg_match_all('/' . $test . '(.+?)' . $test2 . '/s', $xml, $matches);
...