Perl将2个regexp合并为1个



一个有效的字符串应该只包含西里尔字符或拉丁字符。

我用2个regexp创建了一个工作解决方案。但是当我试图将它们合并为一个时,它失败了:

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use v5.14;
use open ':std', ':encoding(UTF-8)';
my @data = (
# rus - ok
"абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ",
# space
"а бвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ",
# rus - latin
"аtбвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ",
# digit
"аб2вгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ",
# latin - ok
"abcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",
# space
"a bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",
# underscore
"a_bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",
# digit
"a2bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ"
);
foreach(@data) {
if ($_ =~ /^[а-яё]+$/i or $_ =~ /^[a-z]+$/i) {
print "okn";
}
else {
print "badn";
}
}
print "-------n";
foreach(@data) {
if ($_ =~ /^(:?[а-яё]+)|(:?[a-z]+)$/i) {
print "okn";
}
else {
print "badn";
}
}

输出:

ok
bad
bad
bad
ok
bad
bad
bad
-------
ok
ok
ok
ok
ok
ok
ok
ok

由于某些原因,第二个regexp总是成功。

在你的正则表达式中

  • :?-匹配一个可选的:,而您想要定义一个非捕获组,(?:...)
  • ^(?:a+)|(?:b+)$-匹配字符串开头的as或字符串末尾的bs。

你应该使用

/^(?:[а-яё]+|[a-z]+)$/i

参见regex演示。细节:

  • ^-字符串
  • 起始
  • (?:—非抓包组启动
    • [а-яё]+-一个或多个俄罗斯字母
    • |-或
    • [a-z]+-一个或多个ASCII字母
  • )-非捕获组结束
  • $-字符串结束

注意从Perl 5.22开始,您可以使用n修饰符使捕获组表现为非捕获,/^([а-яё]+|[a-z]+)$/ni。因此,不存在?::?混合的风险。

在本例中检查use v5.22.0;的核心版本。

最新更新