Perl Regular Expression игнорируется? - PullRequest
0 голосов
/ 09 ноября 2011

Извините, если это не достойно переполнения стека, но я в тупике.Вот мой код:

#Search tmpData for a <whack> tag and replace with REPLACEMENTSTRING (this works)
$tmpData =~ s/<\s*whack\s+([^\/>]*)(\/?>)/"$REPLACEMENTSTRING"/i;

if($defaultData ne '') {
print "pre $1 And $2... '$&'\n";

#Search for data inside <whack> tag and closing tag </whack> and remove them.
$tmpData =~ s/$defaultData<\/whack>$//;
print "FOUND $1 And $2... '$&'\n";  

Для тех, кто не знает, $& показывает соответствие регулярному выражению.Проблема в том, что второе регулярное выражение, по-видимому, вообще не выполняется: последний оператор print отображает все значения из первого регулярного выражения.Вы ожидаете, что $& изменит здесь.Правильно?

Мои тестовые данные: $tmpData is: yo "WHACKREPLACEMENT-idname2"helloworld</whack>

после первого регулярного выражения.$defaultData is: helloworld

Я попытался вытащить этот код из основного скрипта в тестовый файл, который не является строгим, и он работал: (

Что происходит ?! Спасибо!

РЕДАКТИРОВАТЬ Я не был уверен, как сделать это более понятным, поэтому я решил опубликовать вывод из моего отладчика в точке ошибки:

main: :( c: \exec \ webwhack.pl: 109): $ tmpData = ~ s / $ defaultData $ //;

DB <2> p $ tmpData, $ defaultData

"WHACKATAG2837293REPLACEMENT-idname2" removeMe

removeMe

DB <3> n

main: :( c: \ exec \ webwhack.pl: 110): print "FOUND $ 1 And $ 2 ... '$ &' \ n";

DB <3> p $ tmpData,$ defaultData

"WHACKATAG2837293REPLACEMENT-idname2" removeMe

removeMe

Таким образом, вы можете видеть, что входя вв конце строки существует регулярное выражение "removeMe". Выходит из регулярного выражения, как будто ничего не изменилось:(

EDIT2

Следует также отметить, что все эти операторы заключены в:

while( $tmpData =~ m/<\s*whack\s+([^\/>]*)(\/?>)/ig) { ... }

цикл

Ответы [ 4 ]

2 голосов
/ 09 ноября 2011

Трудно сказать точно, без значений $defaultData и $tmpData, но это будет то, что вы увидите, когда ваш шаблон $defaultData не сопоставляется во втором =~.

В конце концов, man perlvar говорит:

$ & Строка, соответствующая последнему успешному сопоставлению с образцом

I 'd структурировать это так:

#Search tmpData for a <whack> tag and replace with REPLACEMENTSTRING (this works)
$tmpData =~ s/<\s*whack\s+([^\/>]*)(\/?>)/"$REPLACEMENTSTRING"/i;

if($defaultData ne '') {
  print "pre $1 And $2... '$&'\n";

  #Search for data inside <whack> tag and closing tag </whack> and remove them.
  if($tmpData =~ s/$defaultData<\/whack>$//) { 
    print "FOUND $1 And $2... '$&'\n";  
  } else { 
    print "NOT FOUND";
  } 
}
1 голос
/ 09 ноября 2011

Почему должно выполняться второе регулярное выражение? yo "WHACKREPLACEMENT-idname2" helloworld не заканчивается на </whack>. Помните, что $ 1, $ 2 и $ & содержат значения из последнего успешного совпадения, которое в вашем случае является первым регулярным выражением.

EDIT:

Спасибо за отрицательный голос. Мой оригинальный ответ все еще остается верным. Причина, по которой $1, $2, $& и $tmpData не меняется, заключается в том, что ваше второе регулярное выражение ничего не соответствует в $tmpData. Если бы вы изменили свой код, чтобы показать соответствующий код, чтобы мы могли видеть, что происходит, было бы легко указать точно, почему. Вместо этого вы разместили больше неактуальной информации.

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

#!/usr/bin/perl -w

use strict;

my $defaultData = "yo";
my $tmpData = "$defaultdata <whack id='IcedDante'>helloworld</whack>";
my $REPLACEMENTSTRING = "WHACKREPLACEMENT-idname";

#Search tmpData for a <whack> tag and replace with REPLACEMENTSTRING (this works)

$tmpData =~ s/<\s*whack\s+([^\/>]*)(\/?>)/"$REPLACEMENTSTRING"/i;

if($defaultData ne '') {
    print "pre $1 And $2... '$&'\n";

    #Search for data inside <whack> tag and closing tag </whack> and remove them.
    $tmpData =~ s/$defaultData<\/whack>$//;
    print "FOUND $1 And $2... '$&'\n";  
}

(Я пытался восстановить ваш код на основе информации, которую вы нам дали, но это было невозможно.)

1 голос
/ 09 ноября 2011

Я предполагаю, что ваша первая операция замены изменяет $ tmpData так, что второй шаблон замены не совпадает.

Тем не менее, я думаю, что вы могли бы упростить свой код с помощью одной операции замены, если вы 'просто пытаемся понять, что у вас внутри, вот так:

if ($tmpdata =~ s/<whack>(.*?)<\/whack>/$1/) {

    print "Found whack tag value: $tmpdata\n";
}

Обновление: исправлена ​​косая черта

0 голосов
/ 09 ноября 2011

Извините, ребята, проблема в том, что я не сжал строку ввода файла, и в результате $ defaultData в конце регулярного выражения имел символ '\ n'.

Чтобы не допустить, чтобы это стало полной катастрофой, я объясню, что я сделал, в надежде, что это поможет кому-то еще в будущем. Ошибка в логике произошла еще до того, как этот код был достигнут. Я пытался извлечь данные между открывающим и закрывающим тегом «whack»:

<whack>Extract this data.</whack>

Используя этот код:

$defaultData = substr $tmpData, pos($tmpData);
$defaultData =~ s/(.+)<\/whack>/$1/;

Я не понимал, что этот код будет извлекать весь текст до "", и все после тега в этой строке . В данном случае это был перевод строки. Я заменил регулярное выражение на:

$defaultData =~ s/(.+)<\/whack>.*/$1/;

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

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