Làm cách nào để tạo chuỗi với các ký tự unicode không hợp lệ, trong Zsh?


7

Đối với một số mục đích thử nghiệm, tôi cần một chuỗi có các ký tự unicode không hợp lệ. Làm thế nào để tạo chuỗi như vậy trong Zsh?

Câu trả lời:


15

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\UXXXXXXXXtrì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 ( perlcũ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 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 grepvẫ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 grepkhác hoặc các tiện ích khác.


Có gì shell làfor c ($l) print -r ${(P)c} |
iruvar

1
@ 1_CR, câu hỏi khá rõ ràng là chúng ta đang nói đến cái vỏ nào ở đây vì nó nằm trong chủ đề, nội dung và thẻ.
Stéphane Chazelas 7/12/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.