Как я могу вставить контент между 2-м и 3-м абзацами в HTML, используя Perl? - PullRequest
3 голосов
/ 28 апреля 2010

Я пытаюсь сопоставить точку между 2-м и 3-м абзацами, чтобы вставить некоторый контент. Абзацы разделены либо <p>, либо двумя символами новой строки, смешанными. Вот пример:

текстовый текст текстовый текст
текст текст текст текст

<p>
текст текст текст текст
текст текст текст текст
</p>
<--------------------------- хотите вставить текст сюда <br> <p>
текст текст текст текст
текст текст текст текст
</p>

Ответы [ 3 ]

3 голосов
/ 28 апреля 2010

Если нет вложенных абзацев ...

my $to_insert = get_thing_to_insert();
$text =~ s/((?:<p>.*?</p>|\n\n){2})/$1$to_insert/s;

должен вот-вот сделать.

С расширенным форматированием:

$text =~ s{
    (             # a group
        (?:       # containing ...
            <p>   # the start of a paragraph
            .*?   # to...
            </p>  # its closing tag
        |         # OR...
           \n\n   # two newlines alone. 
        ){2}      # twice
    )             # and take all of that...
}
{$1$to_insert}xms # and append $val to it

Обратите внимание, я использовал \ n \ n в качестве разделителя; если вы используете текстовый файл в стиле Windows, это должно быть \r\n\r\n, или, если оно может быть смешанным, что-то вроде \r?\n\r?\n, чтобы сделать \r необязательным.

Также обратите внимание, что, поскольку '\ n \ n' находится после |, блоки <p> могут содержать двойные символы новой строки - приоритет от <p> до </p> Если вы хотите, чтобы новые строки внутри <p> имели приоритет, меняйте их местами.

0 голосов
/ 29 апреля 2010

Вместо использования регулярного выражения используйте средство просмотра дерева HTML, чтобы найти второй абзац и добавить все, что вам нравится. Я говорил об этом в моем Процессе HTML с модулем Perl для InformIT.

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

Пример HTML :: TreeBuilder выглядит примерно так:

#!perl
use strict;
use warnings;

use HTML::TreeBuilder;
use HTML::Element;

my $html  = HTML::TreeBuilder->new;
my $root  = $html->parse_file( *DATA );

my $second = ( $root->find_by_tag_name('p') )[1];

my $new_para = HTML::Element->new( 'p' );
$new_para->push_content( 'Add this line' );

$second->postinsert( $new_para );

print $root->as_HTML( undef, "\t", {} );

__END__
<p>
This is the first paragraph
</p>

<p>
This is the second paragraph
</p>

<p>
This is the last paragraph
</p>

Если вам нужно сначала очистить данные, вы можете добавить несколько шагов, чтобы использовать HTML :: Tidy с опцией enclose_text.

0 голосов
/ 28 апреля 2010

Текст:

my $text = '
text text text text
text text text text

<p>
text text text text
text text text text
</p>
<p>
text text text text
text text text text
</p>
';

Это должно работать с:

our $cnt = 0;
our $where = 2;

my $new_stuff='<- want to insert text here';
$text =~ s/
           (
            (?:\n|<\/p>)\n
           )
           (?{ ++$cnt })
           (??{ $cnt==$where?'':'!$' })
          /$1$new_stuff\n/xs;

Результат:

text text text text
text text text text

<p>
text text text text
text text text text
</p>
<- want to insert text here
<p>
text text text text
text text text text
</p>

Привет

БВУ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...