Perl 将 2 个正则表达式合并为 1 个

use*_*035 3 regex perl

有效的字符串应仅包含西里尔字符或拉丁字符。

\n

我使用 2 个正则表达式创建了一个工作解决方案。但是当我尝试将它们合并为 1 时,它失败了:

\n
#!/usr/bin/perl\n\nuse strict;\nuse warnings;\nuse utf8;\nuse v5.14;\nuse open ':std', ':encoding(UTF-8)';\n\nmy @data = (\n    # rus - ok\n    "\xd0\xb0\xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4\xd0\xb5\xd1\x91\xd0\xb6\xd0\xb7\xd0\xb8\xd0\xb9\xd0\xba\xd0\xbb\xd0\xbc\xd0\xbd\xd0\xbe\xd0\xbf\xd1\x80\xd1\x81\xd1\x82\xd1\x83\xd1\x84\xd1\x85\xd1\x86\xd1\x87\xd1\x88\xd1\x89\xd1\x8c\xd1\x8b\xd1\x8a\xd1\x8d\xd1\x8e\xd1\x8f\xd0\x90\xd0\x91\xd0\x92\xd0\x93\xd0\x94\xd0\x95\xd0\x81\xd0\x96\xd0\x97\xd0\x98\xd0\x99\xd0\x9a\xd0\x9b\xd0\x9c\xd0\x9d\xd0\x9e\xd0\x9f\xd0\xa0\xd0\xa1\xd0\xa2\xd0\xa3\xd0\xa4\xd0\xa5\xd0\xa6\xd0\xa7\xd0\xa8\xd0\xa9\xd0\xac\xd0\xab\xd0\xaa\xd0\xad\xd0\xae\xd0\xaf",\n    # space\n    "\xd0\xb0 \xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4\xd0\xb5\xd1\x91\xd0\xb6\xd0\xb7\xd0\xb8\xd0\xb9\xd0\xba\xd0\xbb\xd0\xbc\xd0\xbd\xd0\xbe\xd0\xbf\xd1\x80\xd1\x81\xd1\x82\xd1\x83\xd1\x84\xd1\x85\xd1\x86\xd1\x87\xd1\x88\xd1\x89\xd1\x8c\xd1\x8b\xd1\x8a\xd1\x8d\xd1\x8e\xd1\x8f\xd0\x90\xd0\x91\xd0\x92\xd0\x93\xd0\x94\xd0\x95\xd0\x81\xd0\x96\xd0\x97\xd0\x98\xd0\x99\xd0\x9a\xd0\x9b\xd0\x9c\xd0\x9d\xd0\x9e\xd0\x9f\xd0\xa0\xd0\xa1\xd0\xa2\xd0\xa3\xd0\xa4\xd0\xa5\xd0\xa6\xd0\xa7\xd0\xa8\xd0\xa9\xd0\xac\xd0\xab\xd0\xaa\xd0\xad\xd0\xae\xd0\xaf",\n    # rus - latin\n    "\xd0\xb0t\xd0\xb1\xd0\xb2\xd0\xb3\xd0\xb4\xd0\xb5\xd1\x91\xd0\xb6\xd0\xb7\xd0\xb8\xd0\xb9\xd0\xba\xd0\xbb\xd0\xbc\xd0\xbd\xd0\xbe\xd0\xbf\xd1\x80\xd1\x81\xd1\x82\xd1\x83\xd1\x84\xd1\x85\xd1\x86\xd1\x87\xd1\x88\xd1\x89\xd1\x8c\xd1\x8b\xd1\x8a\xd1\x8d\xd1\x8e\xd1\x8f\xd0\x90\xd0\x91\xd0\x92\xd0\x93\xd0\x94\xd0\x95\xd0\x81\xd0\x96\xd0\x97\xd0\x98\xd0\x99\xd0\x9a\xd0\x9b\xd0\x9c\xd0\x9d\xd0\x9e\xd0\x9f\xd0\xa0\xd0\xa1\xd0\xa2\xd0\xa3\xd0\xa4\xd0\xa5\xd0\xa6\xd0\xa7\xd0\xa8\xd0\xa9\xd0\xac\xd0\xab\xd0\xaa\xd0\xad\xd0\xae\xd0\xaf",\n    # digit\n    "\xd0\xb0\xd0\xb12\xd0\xb2\xd0\xb3\xd0\xb4\xd0\xb5\xd1\x91\xd0\xb6\xd0\xb7\xd0\xb8\xd0\xb9\xd0\xba\xd0\xbb\xd0\xbc\xd0\xbd\xd0\xbe\xd0\xbf\xd1\x80\xd1\x81\xd1\x82\xd1\x83\xd1\x84\xd1\x85\xd1\x86\xd1\x87\xd1\x88\xd1\x89\xd1\x8c\xd1\x8b\xd1\x8a\xd1\x8d\xd1\x8e\xd1\x8f\xd0\x90\xd0\x91\xd0\x92\xd0\x93\xd0\x94\xd0\x95\xd0\x81\xd0\x96\xd0\x97\xd0\x98\xd0\x99\xd0\x9a\xd0\x9b\xd0\x9c\xd0\x9d\xd0\x9e\xd0\x9f\xd0\xa0\xd0\xa1\xd0\xa2\xd0\xa3\xd0\xa4\xd0\xa5\xd0\xa6\xd0\xa7\xd0\xa8\xd0\xa9\xd0\xac\xd0\xab\xd0\xaa\xd0\xad\xd0\xae\xd0\xaf",\n    # latin - ok\n    "abcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",\n    # space\n    "a bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",\n    # underscore\n    "a_bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ",\n    # digit\n    "a2bcdefghejklmnopqrstuvwxyzABCDEFGHEJKLMNOPQRSTUVWXYZ"\n);\n\nforeach(@data) {\n    if ($_ =~ /^[\xd0\xb0-\xd1\x8f\xd1\x91]+$/i or $_ =~ /^[a-z]+$/i) {\n        print "ok\\n";\n    }\n    else {\n        print "bad\\n";\n    }\n}\n\nprint "-------\\n";\nforeach(@data) {\n    if ($_ =~ /^(:?[\xd0\xb0-\xd1\x8f\xd1\x91]+)|(:?[a-z]+)$/i) {\n        print "ok\\n";\n    }\n    else {\n        print "bad\\n";\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
ok\nbad\nbad\nbad\nok\nbad\nbad\nbad\n-------\nok\nok\nok\nok\nok\nok\nok\nok\n
Run Code Online (Sandbox Code Playgroud)\n

由于某种原因,第二个正则表达式总是成功。

\n

Wik*_*żew 5

在你的正则表达式中,

\n
    \n
  • :?:-当您想要定义非捕获组时匹配可选的,(?:...)
  • \n
  • ^(?:a+)|(?:b+)$- 匹配a字符串开头的 s 或b字符串末尾的 s。
  • \n
\n

你应该使用

\n
/^(?:[\xd0\xb0-\xd1\x8f\xd1\x91]+|[a-z]+)$/i\n
Run Code Online (Sandbox Code Playgroud)\n

请参阅正则表达式演示细节

\n
    \n
  • ^- 字符串的开头
  • \n
  • (?:- 非捕获组的开始\n
      \n
    • [\xd0\xb0-\xd1\x8f\xd1\x91]+- 一个或多个俄语字母
    • \n
    • |- 或者
    • \n
    • [a-z]+- 一个或多个 ASCII 字母
    • \n
    \n
  • \n
  • )- 非捕获组结束
  • \n
  • $- 字符串末尾。
  • \n
\n

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

\n

在这种情况下检查核心版本use v5.22.0;

\n