![为什么此正则表达式会找到 \x63 与模式 [\80-\BF] 的匹配项](https://linux22.com/image/1620/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%AD%A4%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%BC%9A%E6%89%BE%E5%88%B0%20%5Cx63%20%E4%B8%8E%E6%A8%A1%E5%BC%8F%20%5B%5C80-%5CBF%5D%20%E7%9A%84%E5%8C%B9%E9%85%8D%E9%A1%B9.png)
我正在尝试过滤有效/无效的 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
这样失踪的人更加突出。