Perl正则表达式是否被忽略?

2w3kk1z5  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(255)

抱歉,如果这不是堆栈溢出值得,但我难倒了。这是我的代码:

#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之后
我试着把这段代码从主脚本中提取出来,放到一个不严格的测试文件中,结果成功了:(
怎么回事?!谢谢!

EDIT我不知道如何使它更清楚,所以我想我应该在错误点发布调试器的输出:

请输入您的密码:$tmpData =~ s/$默认数据$//;
数据库 <2>p $临时数据,$默认数据

“WHACKATAG 2837293替换标识名2“删除我
删除我

数据库<3>n
请输入您的密码:print“找到$1和$2...'$&'\n”;
数据库 <3>p $临时数据,$默认数据

“WHACKATAG 2837293替换标识名2“删除我
删除我

因此,你可以看到,进入正则表达式“removeMe”时,它位于字符串的末尾。而从正则表达式出来时,它就好像什么都没有改变。:(

编辑2

我还应该指出,所有这些陈述都是用一句话 Package 起来的:

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

回路

wooyq4lh

wooyq4lh1#

如果$defaultData$tmpData没有值,很难准确地说出来,但当您的$defaultData模式在第二个=~中不匹配时,就会看到这样的结果。
毕竟,曼 perl 瓦说:
$与上次成功模式匹配匹配的字符串(& T)
我会这样组织它:

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

5t7ly7z52#

我猜您的第一个替换操作是更改$tmpData,从而使第二个替换模式不匹配。
也就是说,我认为如果你只是想获取你的whack tag中的内容,你可以用一个替换操作来简化你的代码,如下所示:

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

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

更新:修正了斜线

s71maibg

s71maibg3#

为什么要执行第二个正则表达式?yo“WHACKREPLACEMENT-idname 2“helloworld不以</whack>结尾。请记住,$1、$2和$&包含最后一个成功匹配的值,在您的示例中,它是第一个正则表达式。
$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";  
}

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

px9o7tmv

px9o7tmv4#

对不起,伙计们,问题是我没有咀嚼我的文件输入行,结果$defaultData在正则表达式的结尾有一个“\n”字符。
为了保存这段代码成为一场灾难,我将解释我所做的事情,希望它能在将来帮助其他人。逻辑上的错误甚至在到达这段代码之前就发生了。我试图提取开始和结束“whack”标记之间的数据:

<whack>Extract this data.</whack>

使用以下代码:

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

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

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

当然,这将是不可能确定的基础上,我提供了在原来的问题,我会尝试做得更好,在未来的工作。

相关问题