Perl正则表达式被忽略了吗?

时间:2011-11-09 07:17:39

标签: regex perl

很抱歉,如果这不是Stack Overflow值得的,但我很难过。这是我的代码:

#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&lt; / whack&gt; $ //;

DB&LT 2 - ; p $ tmpData,$ defaultData

“WHACKATAG2837293REPLACEMENT-idname2” removeMe

removeMe

DB&LT 3的密度; Ñ

main ::(c:\ exec \ webwhack.pl:110):打印“FOUND $ 1和$ 2 ...'$&amp;'\ n”;

DB&LT 3的密度; p $ tmpData,$ defaultData

“WHACKATAG2837293REPLACEMENT-idname2” removeMe

removeMe

所以你可以看到进入正则表达式“removeMe”存在于字符串的末尾。虽然从正则表达式出来 - 好像没什么变化。 :(

EDIT2

我还应该指出所有这些陈述都包含在:

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

4 个答案:

答案 0 :(得分:2)

很难确切地说没有$defaultData$tmpData的值,但这会是您在$defaultData模式未在第二个{{1}中匹配时看到的内容}。

毕竟,man perlvar说:

  

$&安培;与最后成功模式匹配的字符串匹配

我的结构如下:

=~

答案 1 :(得分:1)

我猜你的第一个替换操作正在改变$ tmpData,这样第二个替换模式就不匹配了。

那就是说,如果你只是试图抓住你的打击内容中的内容,我认为你可以用一个替代操作简化你的代码:

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

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

更新:修正了斜杠

答案 2 :(得分:1)

为什么第二个正则表达式会执行? yo“WHACKREPLACEMENT-idname2”helloworld 不以</whack>结尾。请记住$ 1,$ 2和$&amp;包含上一次成功匹配的值,在您的情况下是第一个正则表达式。

修改

感谢投票。我原来的答案仍然适用。 $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";  
}

(我试图从你给我们的信息中重建你的代码,但这是不可能的。)

答案 3 :(得分:0)

对不起家伙,问题是我没有选择我的文件输入行,因此$ defaultData在正则表达式的末尾有一个'\ n'字符。

为了避免这种情况成为一场彻底的灾难,我会解释我的所作所为,希望将来可以帮助其他人。逻辑错误发生在甚至达到此代码之前。我试图在开始和结束“whack”标签之间提取数据:

<whack>Extract this data.</whack>

使用此代码:

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

我没有意识到这段代码会在“”之前提取所有文本,并且在该行上的标记之后的所有内容。在这种情况下,这是一个换行符。我将正则表达式替换为:

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

当然,根据我在原始问题中提供的内容,我们无法确定这一点,并且我将在未来尝试做得更好。