如何检查字符串是否包含 ASCII 码
How to check if a string contains ASCII code
给定一个字符串 A\xC3B
,可以通过这样做将其转换为 utf-8 字符串(参考 link):
"A\xC3B".force_encoding('iso-8859-1').encode('utf-8') #=> "AÃB"
但是,我只想在字符串包含ASCII码时执行操作,即\xC3
。我该如何检查?
试过"A\xC3B".include?("\x")
但没用。
\x
只是一个十六进制转义序列。它本身与编码无关。 US-ASCII 从 "\x00"
到 "\x7F"
(例如 "\x41"
与 "A"
相同,"\x30"
与 "0"
相同)。然而,其余的("\x80"
到 "\xFF"
)不是 US-ASCII 字符,因为它是一个 7 位字符集。
如果要检查字符串是否仅包含 US-ASCII 字符,请调用 String#ascii_only?
:
p "A\xC3B".ascii_only? # => false
p "\x41BC".ascii_only? # => true
基于您的代码的另一个示例:
str = "A\xC3B"
unless str.ascii_only?
str.force_encoding(Encoding::ISO_8859_1).encode!(Encoding::UTF_8)
end
p str.encoding # => #<Encoding:UTF-8>
我想你想做的是弄清楚你的字符串是否被正确编码。 ascii_only?
解决方案在处理非 Ascii 字符串时没有多大帮助。
我会使用 String#valid_encoding?
来验证字符串是否正确编码,即使它包含非 ASCII 字符。
例如,如果其他人以正确的方式对 "Françoise Paré"
进行了编码,而当我对其进行解码时,我得到的是正确的字符串而不是 "Fran\xE7oise Par\xE9"
(如果有人进行了编码,则会被解码它变成 ISO-8859-1)。
[62] pry(main)> "Françoise Paré".encode("utf-8").valid_encoding?
=> true
[63] pry(main)> "Françoise Paré".encode("iso-8859-1")
=> "Fran\xE7oise Par\xE9"
# Note the encoding is still valid, it's just the way IRB displays
# ISO-8859-1
[64] pry(main)> "Françoise Paré".encode("iso-8859-1").valid_encoding?
=> true
# Now let's interpret our 8859 string as UTF-8. In the following
# line, the string bytes don't change, `force_encoding` just makes
# Ruby interpret those same bytes as UTF-8.
[65] pry(main)> "Françoise Paré".encode("iso-8859-1").force_encoding("utf-8")
=> "Fran\xE7oise Par\xE9"
# Is a lone \xE7 valid UTF-8? Nope.
[66] pry(main)> "Françoise Paré".encode("iso-8859-1").force_encoding("utf-8").valid_encoding?
=> false
给定一个字符串 A\xC3B
,可以通过这样做将其转换为 utf-8 字符串(参考 link):
"A\xC3B".force_encoding('iso-8859-1').encode('utf-8') #=> "AÃB"
但是,我只想在字符串包含ASCII码时执行操作,即\xC3
。我该如何检查?
试过"A\xC3B".include?("\x")
但没用。
\x
只是一个十六进制转义序列。它本身与编码无关。 US-ASCII 从 "\x00"
到 "\x7F"
(例如 "\x41"
与 "A"
相同,"\x30"
与 "0"
相同)。然而,其余的("\x80"
到 "\xFF"
)不是 US-ASCII 字符,因为它是一个 7 位字符集。
如果要检查字符串是否仅包含 US-ASCII 字符,请调用 String#ascii_only?
:
p "A\xC3B".ascii_only? # => false
p "\x41BC".ascii_only? # => true
基于您的代码的另一个示例:
str = "A\xC3B"
unless str.ascii_only?
str.force_encoding(Encoding::ISO_8859_1).encode!(Encoding::UTF_8)
end
p str.encoding # => #<Encoding:UTF-8>
我想你想做的是弄清楚你的字符串是否被正确编码。 ascii_only?
解决方案在处理非 Ascii 字符串时没有多大帮助。
我会使用 String#valid_encoding?
来验证字符串是否正确编码,即使它包含非 ASCII 字符。
例如,如果其他人以正确的方式对 "Françoise Paré"
进行了编码,而当我对其进行解码时,我得到的是正确的字符串而不是 "Fran\xE7oise Par\xE9"
(如果有人进行了编码,则会被解码它变成 ISO-8859-1)。
[62] pry(main)> "Françoise Paré".encode("utf-8").valid_encoding?
=> true
[63] pry(main)> "Françoise Paré".encode("iso-8859-1")
=> "Fran\xE7oise Par\xE9"
# Note the encoding is still valid, it's just the way IRB displays
# ISO-8859-1
[64] pry(main)> "Françoise Paré".encode("iso-8859-1").valid_encoding?
=> true
# Now let's interpret our 8859 string as UTF-8. In the following
# line, the string bytes don't change, `force_encoding` just makes
# Ruby interpret those same bytes as UTF-8.
[65] pry(main)> "Françoise Paré".encode("iso-8859-1").force_encoding("utf-8")
=> "Fran\xE7oise Par\xE9"
# Is a lone \xE7 valid UTF-8? Nope.
[66] pry(main)> "Françoise Paré".encode("iso-8859-1").force_encoding("utf-8").valid_encoding?
=> false