Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式工作,但收到警告:在正则表达式错误中多次匹配空字符串_Regex_Perl_Regex Lookarounds - Fatal编程技术网

Regex 正则表达式工作,但收到警告:在正则表达式错误中多次匹配空字符串

Regex 正则表达式工作,但收到警告:在正则表达式错误中多次匹配空字符串,regex,perl,regex-lookarounds,Regex,Perl,Regex Lookarounds,我有一个字符串,其中有许多组件需要提取。这些都是结构良好且可预测的,但它们出现的顺序各不相同。下面是一个片段,它演示了字符串可能是什么样子,以及我用来提取所需信息的正则表达式。这段代码运行正常,我得到了预期的输出 my $str1 = '(test1=cat)(test2=dog)(test3=mouse)'; # prints cat\ndog\mouse $str1 = '(test1=cat)(test3=mouse)(test2=dog)(test1=cat)'; # p

我有一个字符串,其中有许多组件需要提取。这些都是结构良好且可预测的,但它们出现的顺序各不相同。下面是一个片段,它演示了字符串可能是什么样子,以及我用来提取所需信息的正则表达式。这段代码运行正常,我得到了预期的输出

my $str1 = '(test1=cat)(test2=dog)(test3=mouse)';         # prints cat\ndog\mouse
$str1 = '(test1=cat)(test3=mouse)(test2=dog)(test1=cat)'; # prints cat\ndog\nmouse
$str1 = '(test3=mouse)(test1=cat)';                       # prints cat\nempty\nmouse
$str1 = '(test3=mouse)(test2=dog)';                       # prints empty\ndog\nmouse
my $pattern1 = '(?=.*\(test1=(.*?)\))*(?=.*\(test2=(.*?)\))*(?=.*\(test3=(.*?)\))*';

if (my @map = $str1 =~ /$pattern1/) {
    foreach my $match (@map) {
        say $match if $match;
        say "empty" if !$match;
    }
}
上述最后一个字符串的预期和接收结果如下:

empty
dog
mouse
但是,除了预期的响应之外,还有以下警告:

(?=.*\(test1=(.*?)\))* matches null string many times in regex; marked by <-- HERE in m/(?=.*\(test1=(.*?)\))* <-- HERE (?=.*\(test2=(.*?)\))*(?=.*\(test3=(.*?)\))*/ at /path/to/scratch1.pl line 32.
(?=.*\(test2=(.*?)\))* matches null string many times in regex; marked by <-- HERE in m/(?=.*\(test1=(.*?)\))*(?=.*\(test2=(.*?)\))* <-- HERE (?=.*\(test3=(.*?)\))*/ at /path/to/scratch1.pl line 32.
(?=.*\(test3=(.*?)\))* matches null string many times in regex; marked by <-- HERE in m/(?=.*\(test1=(.*?)\))*(?=.*\(test2=(.*?)\))*(?=.*\(test3=(.*?)\))* <-- HERE / at /path/to/scratch1.pl line 32.

(?=.*\(test1=(.*?\)*在正则表达式中多次匹配空字符串;通过多次匹配前瞻
(?=…)
来标记是没有意义的。它不使用对象字符串中的任何数据,因此如果匹配一次,它将无限期地匹配

您需要进行的主要更改是将
(?=.*\(test1=(.*))*
等替换为
(?=.*\(test1=(.*))?
。这只会使你的前瞻性成为“可选的”,并将消除你的警告

使用严格;
使用“全部”警告;
使用数据::转储;
我的$pattern=qr/
(?=.*\(test1=(.*))?
(?=.*\(test2=(.*))?
(?=.*\(test3=(.*))?
/x;
我的@strings=qw/
(test1=cat)(test2=dog)(test3=mouse)
(test1=cat)(test3=mouse)(test2=dog)(test1=cat)
(test3=鼠标)(test1=猫)
(test3=老鼠)(test2=狗)
/;
对于我的$str(@strings){
下一步,除非我的@map=$str=~/$pattern/;
$\uz/=@map的“空”;
dd\@地图;
}
输出
[“猫”、“狗”、“鼠标”]
[“猫”、“狗”、“老鼠”]
[“猫”、“空”、“鼠标”]
[“空”、“狗”、“鼠标”]
然而,这听起来像是另一个让单个正则表达式模式做太多工作的例子。您是用Perl编写的,为什么不使用它呢

以下代码假定与上面的完整程序具有相同的头,包括
@strings
的定义。我只更改了
for
循环的

用于我的$str(@strings){
my@map=map{$str=~/\(test$\=([^()]*)\)/x?$1:'empty'}1..3;
dd\@地图;
}
输出
[“猫”、“狗”、“鼠标”]
[“猫”、“狗”、“老鼠”]
[“猫”、“空”、“鼠标”]
[“空”、“狗”、“鼠标”]
或者可能是一些不同的东西是合适的。哈希对于这类事情很有用

用于我的$str(@strings){
我的%map=$str=~/\((test\d+)=([^()]*)\)/gx;
dd\%map;
}
输出
{test1=>“猫”,test2=>“狗”,test3=>“鼠标”}
{test1=>“猫”,test2=>“狗”,test3=>“老鼠”}
{test1=>“猫”,test3=>“鼠标”}
{test2=>“狗”,test3=>“老鼠”}

之所以发出警告,是因为
(?=…)*
对这一伟大的解释毫无意义。当然要用吗?而不是*做了这个把戏。我喜欢你在没有前瞻性正则表达式的情况下实现它的方式。我会考虑合并它。看起来对我正在做的其他事情也很有用。再次感谢@不客气。经常会遇到这样的问题:作者试图将所有内容都塞进一个正则表达式模式中。这很可能是不必要的,而且对于复杂的条件来说几乎从来都不明智。Perl为您提供了逻辑运算符,因此您可以说
if(/aaa/或/bbb/)…
,而不是
if(/aaa | bbb/)…
,它可以真正改变代码的可读性