Perl 单元 2 正则表达式为 1
Perl unite 2 regexps into 1
有效的字符串应由西里尔字符或仅由拉丁字符组成。
我用 2 个正则表达式创建了一个有效的解决方案。但是当我试图将它们合并为 1 时,它失败了:
#!/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 "ok\n";
}
else {
print "bad\n";
}
}
print "-------\n";
foreach(@data) {
if ($_ =~ /^(:?[а-яё]+)|(:?[a-z]+)$/i) {
print "ok\n";
}
else {
print "bad\n";
}
}
输出:
ok
bad
bad
bad
ok
bad
bad
bad
-------
ok
ok
ok
ok
ok
ok
ok
ok
出于某种原因,第二个正则表达式总是成功。
在你的正则表达式中,
:?
- 当您想定义 non-capturing group、(?:...)
时匹配可选的 :
^(?:a+)|(?:b+)$
- 匹配字符串开头的 a
或字符串结尾的 b
。
你应该使用
/^(?:[а-яё]+|[a-z]+)$/i
参见regex demo。 详情:
^
- 字符串的开头
(?:
- 非捕获组的开始
[а-яё]+
- 一个或多个俄语字母
|
- 或
[a-z]+
- 一个或多个 ASCII 字母
)
- 非捕获组结束
$
- 字符串结尾。
注意:从 Perl 5.22 开始,您可以使用 n
modifier 使捕获组表现为非捕获,/^([а-яё]+|[a-z]+)$/ni
。因此,不存在混合 ?:
和 :?
.
的风险
在这种情况下使用 use v5.22.0;
检查核心版本。
有效的字符串应由西里尔字符或仅由拉丁字符组成。
我用 2 个正则表达式创建了一个有效的解决方案。但是当我试图将它们合并为 1 时,它失败了:
#!/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 "ok\n";
}
else {
print "bad\n";
}
}
print "-------\n";
foreach(@data) {
if ($_ =~ /^(:?[а-яё]+)|(:?[a-z]+)$/i) {
print "ok\n";
}
else {
print "bad\n";
}
}
输出:
ok
bad
bad
bad
ok
bad
bad
bad
-------
ok
ok
ok
ok
ok
ok
ok
ok
出于某种原因,第二个正则表达式总是成功。
在你的正则表达式中,
:?
- 当您想定义 non-capturing group、(?:...)
时匹配可选的 ^(?:a+)|(?:b+)$
- 匹配字符串开头的a
或字符串结尾的b
。
:
你应该使用
/^(?:[а-яё]+|[a-z]+)$/i
参见regex demo。 详情:
^
- 字符串的开头(?:
- 非捕获组的开始[а-яё]+
- 一个或多个俄语字母|
- 或[a-z]+
- 一个或多个 ASCII 字母
)
- 非捕获组结束$
- 字符串结尾。
注意:从 Perl 5.22 开始,您可以使用 n
modifier 使捕获组表现为非捕获,/^([а-яё]+|[a-z]+)$/ni
。因此,不存在混合 ?:
和 :?
.
在这种情况下使用 use v5.22.0;
检查核心版本。