Соответствующая пара тегов с помощью корпуса

StackOverflow https://stackoverflow.com/questions/1692830

  •  18-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь получить определенные теги с их контентом из документа XHTML, но это соответствует неправильным тегам.

В следующем контенте:

<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>

Тег конечного значения content_block для id = "Gellw" на самом деле сопоставлен как окончательный тег первого открывающегося тега content_block.

Покраснение, которую я использую:

/<content_block id="(.*)">([\w\W]*?)<\/content_block>/i

Какие -нибудь указатели относительно того, где я терплю неудачу?

Это было полезно?

Решение

... и ответ всегда одинаковый: Html + regex не может быть сделана. Анкет Извиняюсь. Используйте библиотеку HTML -диаграммы для вашей конкретной структуры. Или, если ваш документ гарантированно содержит только действительный xhtml, примите подход XPath, предложенный Jitter в комментарии.

Другие советы

Это может помочь я нашел учебник на http://www.regular-expressions.info/examples.htmlкоторый упоминает о захвате пары строки, повторяющихся в данном тексте. Предложение - использовать? После.* Чтобы остановиться после первого появления конечной строки пары в тексте

Это известная проблема с Regex - вы не можете сопоставить пары. Сопоставление является либо жадным, в котором он соответствует последнему, который он находит, либо не-восточным, в котором он соответствует первой. Вы не можете убедить регулярность, чтобы считать открытие и закрытие кронштейнов.

Я бы порекомендовал загрузить его в DOM и использовать это. Если вы пытаетесь реализовать анализатор HTML, я бы порекомендовал использовать Regex для лексики, то тогдашний сияющий левый правый для анализа вывода вашего Lexer.

благодаря @Jan żankowski а также @ikegami, их ответ дал мне Inpiration

Позвольте мне использовать PHP, чтобы продемонстрировать код

<?php
$xml = <<<EOT
<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
EOT;

preg_match('/<cache_namespace[^>]+>((?:(?!(<\/?div>)).)*)<\/cache_namespace>/s', $xml, $matches);
print_r($matches);

записка

  • s Вариант: а . В шаблоне совпадает со всеми персонажами, в том числе новичками
  • Ключ здесь в том, что (?:(?!STRING).)* к струнам как [^CHAR]* для персонажей

результат

Array
(
    [0] => <cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
    [1] => 
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>

)

Расположение XHTML или XML не сложно. Я предположил, что у вас есть действительный или хорошо сформированный код.

#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $xml = <<"EOF";
<cache_namespace name="content">
    <content_block id="15">
    some content here

        <cache_namespace name="user">
            <content_block id="welcome">
            Welcome Apikot!
            </content_block>
        </cache_namespace>
    </content_block>
</cache_namespace>
EOF

while ($xml =~ m!
<(content_block)\sid="welcome"> # Start tag definition.
 (\s*                           # It may consists of
   (?: <\!--.*?-->              # - comment
   |  [^<]*                     # - text
   |  <[^>]+/>                  # - another closed tag
   |  <\s*(\w+)[^>]*>           # - another tag with some content
       (?2)+                    # (recursive definition of possible tag content)
      </\3>
   )
 )*
</\1>
!sxgc) {
    print "==> $&\n\n";
}

Пожалуйста, измените определение TAG START для другого контента (например, <\s*(\w+)[^>]*+>) В любом случае, это хорошая начальная точка.

Если вы не будете использовать рекурсию (строить с (?2)+) ты застрянешь Такие примеры. Анкет Этот код может справиться с ними все (пожалуйста, посмотрите здесь раньше) или может легко адаптироваться к новым ситуациям.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top