2013-05-08 2 views
0

В рамках синтаксического анализа сценария Я пытаюсь преобразовать строки, как это:Regex подставляя открывающую скобку

<a href="http://www.web.com/%20Special%20event%202013%20%282%29.pdf"> 

в

<a href="http://www.web.com/%20Special%20event%202013%20(2).pdf"> 

регулярное выражение для закрывающей скобки работает отлично

perl -i -pe "s~(href\=\/?[\"\']\.\.\/$i\-(?:(?!%29).)*)%29([^\"\']*[\"\'])~\1)\2~g" "$pageName".html 

, давая мне

<a href="http://www.web.com/%20Special%20event%202013%20%282).pdf"> 

Проблема arrises с эквивалентным регулярным выражением для открытия круглых скобках:

perl -i -pe "s~(href\=\/?[\"\']\.\.\/$i\-(?:(?!%28).)*)%28([^\"\']*[\"\'])~\1(\2~g" "$pageName".html         

просто возвращает две группы ни с чем между ними:

<a href="http://www.web.com/%20Special%20event%202013%202%29.pdf"> 

побега (в замещении с обратная косая черта (или две) не влияет. Если я обернул его другими символами (скажем ~ \ 1 # (# \ 2 ~ g), скобка все еще исчезает (давая мне% 20 ## 2% 29).

Если, однако, в припадке отчаяния добавляю семь скобок в замене, она работает.

perl -i -pe "s~(href\=\/?[\"\']\.\.\/$i\-(?:(?!%28).)*)%28([^\"\']*[\"\'])~\1(((((((\L\2~g" "$pageName".html 

выходы

<a href="http://www.web.com/%20Special%20event%202013%20(2%29.pdf"> 

Может кто-нибудь, пожалуйста, разобраться в этом.

ответ

0

Узор у вас есть не соответствует строке вы показываете на всех. Это соответствует то, что выглядит как

<a href=/"../$i-xxxxxxxxxxxxxxx%29xxxxxxxxxx"> 

с буквальным точками, и все, что $i содержит.

Кроме того, пара моментов о вашей подмене:

  • Не избежать символов, которые не нуждаются в побеге.Может потребоваться некоторый опыт, чтобы узнать, не проверив, какие символы вам нужно сбежать, но основной смысл использования ~ в качестве разделителя - избежать необходимости сбрасывать косые черты в регулярном выражении, так что по крайней мере вы могли бы избежать этого.

  • Не используйте \1, \2 и т. Д. В заменяемой строке. Perl очень усердно пытается выполнить эту работу, но обычно в Perl эти последовательности означают вставку символов \x01 и \x02. Используйте $1 и $2.

Таким образом, ваш регулярное выражение может быть записано

s~(href=/?["']\.\./$i-(?:(?!%29).)*)%29([^"']*["'])~$1)$2~; 

, но он по-прежнему не «отлично работает» со строкой, вы дали, что должен был бы выглядеть как

<a href=/"../$i-xxxxxxxxxxxxxxx%282%29xxxxxxxxxx"> 

снова, содержащий все, что находится в $i. Я вообще не понимаю необязательную косую черту перед значением атрибута href: это недопустимый HTML.

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

Часто нет необходимости проверять всю строку. Вы можете просто заменить детали, которые вы заинтересованы. Поэтому я хотел бы написать что-то вроде

s/(href="[^"]+)%28(\d+)%29(\.pdf")/$1($2)$3/; 

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

+0

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

+0

Чтобы прояснить пару пунктов: $ i - переменная, потому что это сидит внутри скрипта оболочки. Во-вторых, я знаю, что необязательная косая черта недействительна HTML, я просто пытаюсь разместить все, что вызвал редактор WYSISYG. В конечном счете, хотя критическая оценка, которую вы дали, поставила меня в правильное настроение, чтобы вернуться назад и переоценить ситуацию еще несколько раз, пока я ее не понял. Благодаря! – monototo

+0

Я понял, что '$ i' является переменной оболочки, но я не мог согласовать ваше регулярное выражение со строкой, которую, по вашему утверждению, совпал. Любая строка, которую я попробовал, которая соответствовала первому шаблону, также соответствовала бы второму, поэтому я не смог бы реплицировать вашу проблему. Здесь есть сильный аргумент в том, чтобы написать все это как скрипт Perl, а не зловещую смесь оболочки и Perl, где никто не уверен, сколько обратных косых черт должно быть где угодно. Perl гораздо более универсален, чем любая оболочка, и вы должны сосредоточить свои усилия на тщательном изучении. – Borodin

3

Возможно, следующие будут полезны или, по крайней мере, то или иное направление. это Виль Я работаю над версией Perl версии 10 и выше.

use strict; 
use warnings; 
use v5.10.0; # For regex \K 

use URI::Escape; 

my $string = '<a href="http://www.web.com/%20Special%20event%202013%20%282%29.pdf">'; 
$string =~ s/.+2013%20\K([^.]+)(?=\.pdf)/uri_unescape($1)/e; 
print $string; 

Выход:

<a href="http://www.web.com/%20Special%20event%202013%20(2).pdf"> 

Оставшись достаточно даты и пространства (%20) в качестве якоря, затем используется \Kдо * K * ЕЕР все это. Затем был захвачен кодированный URI текст, который позже декодируется и используется в качестве текста подстановки.

+0

@Borodin - Хорошее редактирование; Спасибо. – Kenosis

+0

Спасибо за этот ответ, оказалось, что проблема была в другом месте моего скрипта (другая замена была удалена родителем), но \ K - удобный оператор для добавления в арсенал. – monototo

+0

@monototo - Добро пожаловать! Хорошо, что вы нашли проблему ... – Kenosis

0

Я имел некоторые проблемы понимания вашего регулярное выражение, но это может работать:

perl -pe "s~(href\s*=\s*\"[^\"]*)%28(.*?)%29~\$1(\$2)~g" input 
Смежные вопросы