我有一个非常疯狂的正则表达式,我正在尝试诊断.它也很长,但我把它简化为以下脚本.使用Strawberry Perl v5.26.2运行.
use strict;
use warnings;
my $text = "M Y H A P P Y T E X T";
my $regex = '(?i)(?<!(Mon|Fri|Sun)day |August )abcd(?-i)';
if ($text =~ m/$regex/){
print "true\n";
}
else {
print "false\n";
}
Run Code Online (Sandbox Code Playgroud)
这给出了错误"正则表达式中没有实现可变长度的后备".
我希望你能帮助解决几个问题:
(?i)
和(?-i)
.当我摆脱(?i)
错误实际上消失了.perl将如何解释这部分正则表达式?我认为前两个字符被评估为"可选的文字括号",除了圆括号没有被转义,在这种情况下我会得到不同的语法错误,因为不会匹配右括号.anu*_*ava 76
我把你的问题减少到了这个:
my $text = 'M Y H A P P Y T E X T';
my $regex = '(?<!st)A';
print ($text =~ m/$regex/i ? "true\n" : "false\n");
Run Code Online (Sandbox Code Playgroud)
由于/i
(不区分大小写)修饰符的存在以及某些字符组合的存在,例如"ss"
或者"st"
可以由Typographic_ligature替换,从而使其成为可变长度(/August/i
例如匹配两个AUGUST
(6个字符)和augu?
(5个字符,最后一个)是U + FB06)).
但是,如果我们删除/i
(不区分大小写)修饰符,那么它的工作原理是因为印刷连字不匹配.
解决方案:使用aa
修饰符,即:
/(?<!st)A/iaa
Run Code Online (Sandbox Code Playgroud)
或者在你的正则表达式中:
my $text = 'M Y H A P P Y T E X T';
my $regex = '(?<!(Mon|Fri|Sun)day |August )abcd';
print ($text =~ m/$regex/iaa ? "true\n" : "false\n");
Run Code Online (Sandbox Code Playgroud)
来自perlre:
要禁止ASCII /非ASCII匹配(例如"k"和"\ N {KELVIN SIGN}"),请指定"a"两次,例如
/aai
或/aia
.(第一次出现"a"限制\d
等等,第二次出现会增加"/ i"限制.)但是,请注意,ASCII范围之外的代码点将使用Unicode规则进行/i
匹配,因此修饰符不会真的把事情限制在ASCII; 它只是禁止ASCII和非ASCII的混合.
cho*_*oba 21
那是因为st
可以是一个结扎线.同样的情况,以fi
和ff
:
#!/usr/bin/perl
use warnings;
use strict;
use utf8;
my $fi = '?';
print $fi =~ /fi/i;
Run Code Online (Sandbox Code Playgroud)
因此,想象一下?|fi
,事实上,替代品的长度并不相同.