【问题标题】:Perl Regular Expression is being ignored?Perl 正则表达式被忽略了?
【发布时间】:2011-11-09 07:17:39
【问题描述】:

对不起,如果这不值得 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";  

对于那些不知道的人,$&amp; 显示正则表达式匹配。问题是第二个正则表达式似乎根本没有执行:最后一个打印语句显示了第一个正则表达式的所有值。你会期望$&amp; 会在这里修改。对吧?

我的测试数据是:$tmpData is: yo "WHACKREPLACEMENT-idname2"helloworld&lt;/whack&gt;

在第一个正则表达式之后。 $defaultData is: helloworld

我尝试将这段代码从主脚本中提取到一个不严格的测试文件中并且它有效:(

这是怎么回事?!谢谢!

编辑 我不知道如何让这个更清楚,所以我想我会在错误点发布我的调试器的输出:

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

DB p $tmpData, $defaultData

“WHACKATAG2837293REPLACEMENT-idname2”removeMe

删除我

数据库 n

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

数据库 p $tmpData, $defaultData

“WHACKATAG2837293REPLACEMENT-idname2”removeMe

删除我

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

EDIT2

我还应该指出,所有这些语句都包含在一个:

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

循环

【问题讨论】:

  • 发布时请考虑发布可复制的内容。我们不是神,不知道你的变量包含什么。
  • 在我发布答案后,似乎对问题进行了一些细微的更改,这使其无效。我建议您发布整个相关代码,而不是其中的部分代码,并附上您对正在发生的事情的解释。目前无法提供任何有意义的帮助。
  • 大家好,我没有对这个问题做任何“细微的改变”......你在说什么?很抱歉没有更详细地说明这一点 - 我将开始查看并了解如何澄清它。
  • 那么我很抱歉。但是,这些修订并没有使任何事情变得更清楚。您应该在代码中包含变量初始化。事实上,如果没有严格和警告,您发布的代码甚至是无效的。

标签: regex perl


【解决方案1】:

很难确切地说没有 $defaultData$tmpData 的值,但是当您的 $defaultData 模式与第二个 =~ 不匹配时,您会看到这种情况。

毕竟,man perlvar 说:

$& 上一次成功模式匹配所匹配的字符串

我会这样安排:

#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";
  } 
}

【讨论】:

    【解决方案2】:

    我猜你的第一个替换操作正在更改 $tmpData 使得第二个替换模式不匹配。

    也就是说,如果您只是想像这样抓取您的重击标签中的内容,我认为您可以通过一个替代操作来简化您的代码:

    if ($tmpdata =~ s/<whack>(.*?)<\/whack>/$1/) {
    
        print "Found whack tag value: $tmpdata\n";
    }
    

    更新:修正斜线

    【讨论】:

    • 是的,我可能会走这条路……但首先,我想弄清楚出了什么问题!
    • 我会尝试将 $tmpdata 打印到控制台以进行调试。如果结尾有空格字符,我总是在输出中使用单引号: print "'$tmpdata'\n";
    【解决方案3】:

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

    编辑:

    感谢您的反对票。我原来的答案仍然成立。 $1$2$&amp;$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";  
    }
    

    (我试图根据您提供给我们的信息重构您的代码,但这是不可能的。)

    【讨论】:

    • 很抱歉投了反对票。我想我刚刚看到两个赞成票,而您的回答对我的情况不正确。不是你的错,这完全是我的不够清楚,但在这种情况下 defaultData 是 标签的 innerText 。非常感谢您抽出宝贵时间提供答案,并希望我的反对意见不会损害您的代表。
    【解决方案4】:

    对不起,问题是我没有压缩文件输入行,结果 $defaultData 在正则表达式的末尾有一个 '\n' 字符。

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

    <whack>Extract this data.</whack>
    

    使用此代码:

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

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

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

    当然,根据我在原始问题中提供的内容,这是不可能确定的,我会努力在未来做得更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 2020-08-06
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多