Таким образом, я пишу быстрый сценарий жемчуга, который очищает некоторый HTML-код и выполняет его через HTML-> программа PDF. Я хочу потерять как можно меньше информации, таким образом, я хотел бы расширить свои текстовые области для установки всему тексту, который в настоящее время находится в них. Это означает, в моем случае, определяя номер строк к расчетному значению на основе значения строки в текстовом поле.
Это в настоящее время - regex, который я использую
$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)/80 })"$2>$3<\/textarea>/gis;
К сожалению, Perl, кажется, не распознает то, что мне сказали, был синтаксис для встраивания кода Perl в поиске-и-замене regexs там, какие-либо наркоманы Perl там готовы сказать мне, что я делаю неправильно? С уважением, Zach
Шаблон (?{...})
является экспериментальной функцией для выполнения кода на стороне соответствия, но вы хотите выполнять код на стороне замены. Для этого используйте переключатель регулярного выражения /e
:
#! /usr/bin/perl
use warnings;
use strict;
use POSIX qw/ ceil /;
while (<DATA>) {
s[<textarea rows="(.+?)"(.*?)>(.*?)</textarea>] {
my $rows = ceil(length($3) / 80);
qq[<textarea rows="$rows"$2>$3</textarea>];
}egis;
print;
}
__DATA__
<textarea rows="123" bar="baz">howdy</textarea>
Выход:
<textarea rows="1" bar="baz">howdy</textarea>
Синтаксис, который вы используете для вставки кода, действителен только в части подстановки "совпадение" (левая часть). Чтобы вставить код в правую часть (которая является обычной строкой Perl с двойными кавычками), вы можете сделать следующее:
$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>}
{<textarea rows="@{[ length($3)/80 ]}"$2>$3</textarea>}gis;
Здесь используется идиома Perl "some string @{[ embedded_perl_code() ]} more string"
.
Но если вы работаете с очень сложным выражением, может быть проще перевести подстановку в режим "eval", где она будет рассматривать заменяющую строку как код Perl:
$file =~ s{<textarea rows="(.+?)"(.*?)>(.*?)</textarea>}
{'<textarea rows="' . (length($3)/80) . qq{"$2>$3</textarea>}}gise;
Обратите внимание, что в обоих примерах regex структурирован как s{}{}
. Это не только избавляет от необходимости экранировать косые черты, но и позволяет распределить выражение по нескольким строкам для удобства чтения.
Это нужно делать с помощью регулярного выражения? Анализ любого языка разметки (или даже CSV) с помощью регулярного выражения чреват ошибкой. Если можете, попробуйте использовать стандартную библиотеку:
http://search.cpan.org/dist/HTML-Parser/Parser.pm
В противном случае вы рискуете отомстить Ктулу:
http: / /www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html
( Да, статья оставляет место для некоторых простых манипуляций со строками, так что я думаю, что ваша душа в безопасности, хотя .: -)
Я полагаю, что ваша проблема заключается в неэскейпированном /
Если это не проблема, то это определенно проблема.
Попробуйте это вместо этого, обратите внимание на \/80
$file=~s/<textarea rows="(.+?)"(.*?)>(.*?)<\/textarea>/<textarea rows="(?{ length($3)\/80 })"$2>$3<\/textarea>/gis;
Основной шаблон для этого кода:
$file =~ s/some_search/some_replace/gis;
gis
- это опции, которые мне придется поискать. Думаю, g = глобальный, i = нечувствительный к регистру, s = ничего не приходит на ум.
Во-первых, вам нужно заключить в кавычки /
внутри выражения в тексте замены (иначе perl увидит оператор s ///, за которым следует число 80
и так далее). Или вы можете использовать другой разделитель; для сложных замен рекомендуется использовать соответствующие скобки.
Затем вы переходите к основной проблеме, которая заключается в том, что (? {...})
доступен только в шаблонах. Текст замены - это не шаблон, это (почти) обычная строка.
Вместо этого есть модификатор e
для оператора s ///
, который позволяет писать выражение замены, а не строку замены.
$file =~ s(<textarea rows="(.+?)"(.*?)>(.*?)</textarea>) ("<textarea rows=\"" . (length($3)/80) . "\"$2>$3</textarea>")egis;