我正在尝试过滤有效/无效的 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
这样失踪的人更加突出。