Unicode 如何检查grapheme是否是一封信?
我如何检查grapheme是否是一个字母(或者经常用于单词中的东西,比如象形文字) 查看Elixir的Unicode 如何检查grapheme是否是一封信?,unicode,internationalization,elixir,Unicode,Internationalization,Elixir,我如何检查grapheme是否是一个字母(或者经常用于单词中的东西,比如象形文字) 查看Elixir的String文档后,我看到的唯一方法是检查String.downcase和String.upcase是否返回相同的字符串。如果他们这样做了,那么字位就不是单词中使用的东西 我就是这样做的,但肯定有更简单的方法吗 defmodule Words do defp all_letters_uppercase?(string) do String.upcase(string) == stri
String
文档后,我看到的唯一方法是检查String.downcase
和String.upcase
是否返回相同的字符串。如果他们这样做了,那么字位就不是单词中使用的东西
我就是这样做的,但肯定有更简单的方法吗
defmodule Words do
defp all_letters_uppercase?(string) do
String.upcase(string) == string
end
defp all_letters_downcase?(string) do
String.downcase(string) == string
end
defp contains_letter?(string) do
not (all_letters_uppercase?(string) and all_letters_downcase?(string))
end
def single_grapheme?(string) do
with graphemes = String.graphemes(string)
do
length(graphemes) == 1 and hd(graphemes) == string
end
end
@doc """
Check whether string is a single letter.
"""
def letter?(string) do
single_grapheme?(string) and contains_letter?(string)
end
end
更新:我的代码不适用于日文字母
iex(35)> Words.letter?("グ")
false
您可以使用正则表达式检查某些unicode功能,其中一个是
\p{Letter}
,简称\p{L}
。您可能需要添加一个\p{Mark}*
,或\p{M}*
,以同时匹配以下多个组合变音符号。这将与String.graphemes/1
中的逻辑紧密匹配。确保在正则表达式之后添加u
修饰符以启用这些Unicode功能。例如:
iex> String.match?("グ", ~r/\A\p{L}\p{M}*\z/u)
true
另请参见“Unicode字符属性”一节和。这似乎工作正常:
defmodule Words do
def letter?(string) do
Regex.match?(~r/^\p{L}$/fu, string)
end
end
iex(51)> Words.letter?("a")
true
iex(52)> Words.letter?("é")
true
iex(53)> Words.letter?("グ")
true
iex(54)> Words.letter?("aa")
false
iex(55)> Words.letter?("1")
false
iex(56)> Words.letter?("-")
false
iex(57)> Words.letter?("")
false
iex(58)> Words.letter?(" ")
false
iex(59)> Words.letter?("éé")
false
iex(60)> Words.letter?("a ")
false
仅限我的2个字符:如果要匹配整个输入字符串,还可以使用
\A
(字符串开头)和\z
(字符串结尾)锚。我发现^
(行首)加上$
(行尾)再加上f
(第一行)修饰符表达的意图不太清晰。@PatrickOscity很有趣,我甚至不知道这些锚存在。出于某种原因,每个人和他们的狗都会使用^
和$
。这似乎与包含字母和组合字符的多码点图形不匹配,例如Words.letter?(“g̉”)#=>false
,而问题中的代码返回true。您可以使用\p{L}\p{M}*
匹配任意数量的下列组合变音符号。@CrabMan组合标记可以任意组合,形成字符和变音符号的任意组合。但是,许多常用组合也可用于als预合成字符。或者,您只能使用String.normalize(输入:nfc)
匹配预合成字符,然后只匹配\p{L}
。不过,我认为匹配组合标记也没什么坏处String.graphemes/1
也将这些字符视为一个字符,因此您将与此逻辑非常匹配。还编辑了我的答案,包括合并分数。