Я пытаюсь фильтровать допустимые / недопустимые байты 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
Похоже, вы забыли x
в последней части регулярного выражения:
[\80-\xBF] --> [\x80-\xBF]
Вы заметили ошибку, хорошо. Теперь было бы полезно выявить подобные ошибки или избежать их в будущем.
Вы уже применили модификатор x
Perl к операторам regexp, который позволяет иметь пробелы в регулярных выражениях. Ваша соответствующая конструкция будет написана с помощью новых строк (что позволит добавлять комментарии).
/( ( ([\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
выделяется больше.