如何判断非语言字符?

时间:2019-03-07 06:03:06

标签: erlang elixir

我描述的标题可能被误解了:

  • 可以是中文/日语或其他任何国家/地区的语言,例如你好こんにちは
  • 可以是英文字母A-Za-z
  • 不能是符号,例如!!,,
  • 不能是表情符号或其他符号之类的特殊字符

可以用长生不老药的二进制字节数还是Unicode来判断?

1 个答案:

答案 0 :(得分:1)

如果我很好地理解了您的问题,那么您想检查给定的字符串是否包含中文/日语字符或字母字符。而不是标点符号或表情符号?

对于亚洲字符,您可以使用Unicode中的CJK range,它可能足够接近。您始终可以check more ranges表示想要(禁止)使用的语言。

所以第一步将是检查给定的代码点是否在CJK range(s)中:

  def is_in_range?(cp) do
    ranges = [
      {"\u4E00", "\u9FEF"},
      {"\u3400", "\u4DBF"},
      {"\u20000", "\u2A6DF"},
      {"\u2A700", "\u2B73F"},
      {"\u2B740", "\u2B81F"},
      {"\u2B820", "\u2CEAF"},
      {"\u2CEB0", "\u2EBEF"},
      {"\u3007", "\u3007"}
    ]

    # Check if the codepoint is any of the ranges above.
    ranges
    |> Enum.map(fn {s, e} ->
      cp >= s and cp <= e
    end)
    |> Enum.any?()
  end

如果拥有该功能,我们可以检查任何给定的字符串是否包含以下任何字符:

  def contains_cjk(str) do
    str |> String.codepoints() |> Enum.map(&is_in_range?/1) |> Enum.any?()
  end

如果要比较字母字符,可以使用常规的正则表达式,也可以仅将范围从AZ,az(\u0061\u007A,将\u0041到{{1 }})。例如,第二个字符串(\u005A)的第一个代码点位于“平假名”代码块中。您可以添加范围(こんにちは\u3040)以也允许这些字符。可以找到here的块列表。

此处有关于性能的注释。该代码不是线性的,因为对于\u309F个字符,它将进行n个比较。