为什么此正则表达式会找到 \x63 与模式 [\80-\BF] 的匹配项

为什么此正则表达式会找到 \x63 与模式 [\80-\BF] 的匹配项

我正在尝试过滤有效/无效的 UTF-8 字节,但从以下正则表达式(旨在处理 3 字节形式的 UTF-8)中得到奇怪的结果。

我的意图是该模式应该不是匹配测试字节'\xE0\xA1\x63',但它确实...
我错过了什么?

showmatch() {
  echo -ne "    --> "
  echo -ne "$bytes" | 
    # strip whitespace from the pattern
    perl -l -ne '/^'${1// /}'$/x and print' |
      tr -d '\n' |
        xxd -p |
          tr -d '\n'
  echo; 
}

bytes='\xE0\xA1\x63'
echo -n "before: "; echo -ne "$bytes" |xxd -p
# Note: all whitespace is stripped from each regex pattern.
#           Bytes 1 and 2 and 3
#          (---------------------------------------------------------------------------------------------------)
#              Bytes 1 and 2
#             (------------------------------------------------------------------------------)                  
#                [byt1][byt2-----]  |  [byt1][byt2-----]  |  [byte-1------------][byt2-----]      [byt3----]                                                          
#                =================     =================     ===============================      ==========                            
showmatch '(  ( ([\xE0][\xA0-\xBF]) | ([\xED][\x80-\x9F]) | ([\xE1-\xEC\xEE-\xEF][\x80-\xBF]) )  ([\80-\xBF])  )'
#
# witout spaces:
showmatch '((([\xE0][\xA0-\xBF])|([\xED][\x80-\x9F])|([\xE1-\xEC\xEE-\xEF][\x80-\xBF]))([\80-\xBF]))'
#
exit

这是输出

before: e0a163
    --> e0a163
    --> e0a163

答案1

看起来您忘记了x正则表达式最后一部分的 an :

[\80-\xBF]  -->  [\x80-\xBF]

答案2

你已经发现了错误,很好。现在有用的是如何发现类似的错误或在将来避免它们。

您已经使用了 Perl 的x正则表达式运算符修饰符,它允许您在正则表达式中包含空格。您的匹配构造将用换行符编写(这将允许您添加注释)。

/(  ( ([\xE0][\xA0-\xBF]) |
      ([\xED][\x80-\x9F]) |
      ([\xE1-\xEC\xEE-\xEF][\x80-\xBF]) )
    ([\80-\xBF])  )/x

或者不带此处不需要的括号:

/([\xE0][\xA0-\xBF]|
  [\xED][\x80-\x9F]|
  [\xE1-\xEC\xEE-\xEF][\x80-\xBF])
 [\80-\xBF] /x

我发现x这样失踪的人更加突出。

相关内容