Câu trả lời:
Tôi giả sử bạn có nghĩa là các ký tự Unicode được mã hóa UTF-8.
Điều đó phụ thuộc vào những gì bạn có nghĩa là không hợp lệ .
invalid_byte_sequence=$'\x80\x81'
Đó là một chuỗi các byte mà bản thân nó không hợp lệ trong mã hóa UTF-8 (byte đầu tiên trong ký tự được mã hóa UTF-8 luôn có hai bit cao nhất được đặt). Chuỗi đó có thể được nhìn thấy ở giữa một ký tự, vì vậy cuối cùng nó có thể tạo thành một chuỗi hợp lệ một khi được nối với một chuỗi không hợp lệ khác như thế nào $'\xe1'
. $'\xe1'
hoặc $'\xe1\x80'
chính họ cũng sẽ không hợp lệ và có thể được coi là một nhân vật bị cắt cụt.
other_invalid_byte_sequence=$'\xc2\xc2'
Byte 0xc2 sẽ bắt đầu ký tự 2 byte và 0xc2 không thể ở giữa ký tự UTF-8. Vì vậy, chuỗi đó không bao giờ có thể được tìm thấy trong văn bản UTF-8 hợp lệ. Tương tự cho $'\xc0'
hoặc $'\xc1'
là các byte không bao giờ xuất hiện trong mã hóa UTF-8.
Đối với \uXXXX
và \UXXXXXXXX
trình tự, tôi giả sử mã hóa của miền địa phương hiện tại là UTF-8.
non_character=$'\ufffe'
Đó là một trong số 66 nhân vật không được chỉ định hiện tại .
not_valid_anymore=$'\U110000'
Unicode hiện bị giới hạn ở các điểm mã lên tới 0x10FFFF. Và mã hóa UTF-8 ban đầu được thiết kế để bao phủ đến 0x7FFFFFFF ( perl
cũng hỗ trợ một biến thể chuyển sang 0xFFFFFFFFFFFFFFFF) hiện cũng bị hạn chế theo quy ước đó.
utf16_surrogate=$'\ud800'
Điểm mã 0xD800 đến 0xDFFF là các điểm mã dành riêng cho mã hóa UTF16. Vì vậy, mã hóa UTF-8 của các điểm mã đó là không hợp lệ.
Bây giờ hầu hết các điểm mã còn lại vẫn chưa được chỉ định trong phiên bản Unicode mới nhất.
unassigned=$'\u378'
Các phiên bản mới hơn của Unicode đi kèm với các ký tự mới được chỉ định. Ví dụ Unicode 8.0 (phát hành vào tháng 6 năm 2015) có ( U + 1F917 ) không được chỉ định trong các phiên bản trước.
unicode_8_and_above_only=$'\U1f917'
Một số thử nghiệm với uconv
:
$ printf %s $invalid_byte_sequence| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: 80 Error: Illegal character found
Conversion to Unicode from codepage failed at input byte position 1. Bytes: 81 Error: Illegal character found
$ printf %s $other_invalid_byte_sequence| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: c2 Error: Illegal character found
Conversion to Unicode from codepage failed at input byte position 1. Bytes: c2 Error: Truncated character found
$ printf %s $non_character| uconv -x any-name
\N{<noncharacter-FFFE>}
$ printf %s $not_valid_anymore| uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: f4 90 80 80 Error: Illegal character found
$ printf %s $utf16_surrogate | uconv -x any-name
Conversion to Unicode from codepage failed at input byte position 0. Bytes: ed a0 80 Error: Illegal character found
$ printf %s $unassigned | uconv -x any-name
\N{<unassigned-0378>}
$ printf %s $unicode_8_and_above_only | uconv -x any-name
\N{<unassigned-1F917>}
$
Với GNU grep
, bạn có thể sử dụng grep .
để xem liệu nó có thể tìm thấy một ký tự trong đầu vào không:
l=(invalid_byte_sequence other_invalid_byte_sequence non_character
not_valid_anymore utf16_surrogate unassigned unicode_8_and_above_only)
for c ($l) print -r ${(P)c} | grep -q . && print $c
Mà cho tôi:
non_character
not_valid_anymore
utf16_surrogate
unassigned
unicode_8_and_above_only
Đó là, tôi grep
vẫn coi một số ký tự không hợp lệ, không phải ký tự hoặc chưa được gán-chưa là ký tự (hoặc chứa). YMMV cho các triển khai grep
khác hoặc các tiện ích khác.
for c ($l) print -r ${(P)c} |