как создать шаблон для preg_match_all - PullRequest
0 голосов
/ 08 ноября 2011

Я пытался погуглить, но ничего не понял.Во-первых, я надеялся, что кто-нибудь может помочь мне написать шаблон для получения информации между этими тегами:

<vboxview leftinset="10" rightinset="0" stretchiness="1">    // CONTENT INSIDE HERE </vboxview>

, а во-вторых, не могли бы вы также подробно объяснить шаблон для каждого раздела, что он делает и как вы?укажите, чтобы получить определенную часть кода.

Ответы [ 2 ]

1 голос
/ 09 ноября 2011

Как уже упоминалось в комментариях, обычно не стоит пытаться извлекать вещи из HTML с помощью регулярных выражений. Если вы когда-нибудь захотите перейти на более пуленепробиваемый метод, приведу краткий пример того, как вы можете легко извлечь информацию, используя DOMDocument API.

<?php
function get_vboxview($html) {

    $output = array();

    // Create a new DOM object
    $doc = new DOMDocument;

    // load a string in as html
    $doc->loadHTML($html);

    // create a new Xpath object to query the document with
    $xpath = new DOMXPath($doc);

    // an xpath query that looks for a vboxview node anywhere in the DOM
    // with an attribute named leftinset set to 10, an attribute named rightinset
    // set to 0 and an attribute named stretchiness set to 1
    $query = '//vboxview[@leftinset=10 and @rightinset=0 and @stretchiness=1]';

    // query the document
    $matches = $xpath->query($query);

    // loop through each matching node
    // and the textContent to the output
    foreach ($matches as $m) {
            $output[] = $m->textContent;
    }

    return $output;
}
?>

Еще лучше, если в вашем входе гарантированно будет только один vboxview (также при условии, что у вас есть контроль над HTML), вы можете добавить атрибут id к vboxview и сократить код до более короткого и более обобщенная функция.

<?php
function get_node_text($html, $id) {
    // Create a new DOM object
    $doc = new DOMDocument;

    // load a string in as html
    $doc->loadHTML($html);

    // return the textContent of the node with the id $id
    return $doc->getElementById($id)->textContent;
}
?>
1 голос
/ 09 ноября 2011

См. Мой комментарий к вопросу о моей напыщенной речи на языках на основе SGML и регулярном выражении ...

Теперь к моему ответу.

Если вы знаете, что не будет никакого другого HTML /Элементы XML внутри рассматриваемого тега, тогда это будет работать довольно хорошо:

<vboxview\s(?P<vboxviewAttributes>(\\>|[^>])*)>(?P<vboxviewContent>(\\<|[^<])*)</vboxview>

Разбитое, это выражение говорит:

<vboxview                  # match `<vboxview` literally
\s+                        # match at least one whitespace character
(?P<vboxviewAttributes>    # begin capture (into a group named "vboxViewAttributes")
   (\\>|[^>])*             #    any number of (either `\>` or NOT `>`)
)                          # end capture
>                          # match a `>` character
(?P<vboxviewContent>       # begin capture (into a group named "vboxViewContent")
   (\\<|[^<])*             #    any number of (either `\<` or NOT `<`)
)                          # end capture
</vboxview>                # match `</vboxview>` literally

Вам нужно будет экранировать и > символоввнутри источника как \> или даже лучше как объекты HTML / XML

Если внутри будут вложенные конструкции, то вы либо начнете сталкиваться с проблемами с регулярным выражением ,или вы уже решили использовать другой метод, который не требует регулярных выражений - в любом случае достаточно!

...