Получение последнего вхождения строки с использованием регулярных выражений - PullRequest
1 голос
/ 07 февраля 2010

Мне нужно разобрать файл HTML, и у меня есть что-то вроде этого:

<TAG1>
    <TAG1>
        TEXT_TO_FIND
        KEY
        <TAG1>
        </TAG1>
        <TAG1>
        </TAG1>
    </TAG1>
</TAG1>

Учитывая, что существует несколько уровней анимирования. Как я могу получить текст TEXT_TO_FIND?

На простом английском языке мне нужно сделать так, чтобы текст был между "последним, у которого есть текст KEY после него", и "текстом KEY", которые появляются в документе только один раз.

Примечание 1: я нашел этот вопрос , но, похоже, он не работал; Я продолжал получать пустой результат. Это было бы выражение:

/<TAG1>(?!.*<TAG1>)(.*)KEY/ism

Примечание 2: Если я уберу КЛЮЧ из выражения предыдущей заметки, я получу текст от последнего до конца файла.

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

Ответы [ 3 ]

1 голос
/ 07 февраля 2010

Привет всем! Мне нужно разобрать файл HTML, и у меня есть что-то вроде этого:

Тогда вам нужен анализатор HTML. Регулярные выражения недостаточно мощны, чтобы делать это правильно.

Как только вы проанализировали HTML и получили содержимое каждого из ваших TAG s, вы можете использовать что-то вроде:

/(.*)KEY/is

, чтобы проверить, содержит ли текст KEY, и если да, то взять материал, предшествующий ему.

0 голосов
/ 08 февраля 2010

Используйте каждый инструмент в соответствующем контексте: найдите фрагменты текста с помощью анализатора HTML, а затем сопоставьте их с регулярными выражениями.

#! /usr/bin/perl

use warnings;
use strict;

use HTML::Parser;

my $p = HTML::Parser->new(
  api_version => 3,
  text_h => [
    sub {
      local($_) = @_;
      print $1, "\n" if /(\S.+?)\s*\bKEY\b/s;
    },
    "dtext"
  ],
);

# for demo only
*ARGV = *DATA;

undef $/;
$p->parse(<>);

__DATA__
<TAG1>
    <TAG1>
        TEXT_TO_FIND
        KEY
        <TAG1>
        </TAG1>
        <TAG1>
        </TAG1>
    </TAG1>
</TAG1>

Выход:

$ ./find-text
TEXT_TO_FIND
0 голосов
/ 07 февраля 2010

Если вы просто не хотите использовать анализатор HTML, это регулярное выражение, которое работает, если TEXT_TO_FIND не содержит "<" или ">":

/\s*([^<>]*?)\s*?KEY/ism
...