【问题标题】:Filtering non-Typeable characters in unicode在 unicode 中过滤不可键入的字符
【发布时间】:2014-05-29 14:55:48
【问题描述】:

在一个在 Delphi 6(非 Unicode 平台)下编写的旧应用程序中,我过去常常通过在 ANSI 字符表中引用它们的单元格编号来过滤掉不可键入的字符( if (aKeyChar in [#32. .#254]) 然后.... ).

现在我转移到基于 Unicode 的平台的 Delphi 2010,这些字符映射不再相关。在 Delphi 2010 中是否有一种干净的方法可以实现这一目标?

【问题讨论】:

  • 使用CharInSet函数?
  • 请定义“不可输入”的含义。我很确定少于 32 的 ASCII 字符是可输入的,如果你知道的话。你的意思是“不可打印”。无论如何,你需要在这里定义你的意思。
  • @whosrdaddy ord(aKeyChar)<32 我认为更干净
  • @DavidHeffernan,完全同意,只是指出 [Enum] 中 x 是 Char 的 x 现在必须使用 CharInSet 函数。
  • @DavidHeffernan,“不可输入”字符是指退格,删除...

标签: delphi unicode delphi-2010


【解决方案1】:

查看System.Character单元中的各种辅助函数,如GetUnicodeCategory()IsControl()IsLetterOrDigit()IsWhiteSpace()等。

【讨论】:

    【解决方案2】:

    在 Unicode 中,要确定代码点是否是控制字符(假设这就是“可键入”的意思),仅查看值是否在集合中是不够的。要获取“控制字符”,您可以查看System.Character 类:

    if Character.IsControl(aKeyChar) then
    

    但请注意,您可能还需要检查 WideChar 是低代理还是高代理,例如

    if Character.IsLowSurrogate(aKeyChar) then
      // is unprintable in and of itself and next WideChar must be a high surrogate.
      // the combination is printable.
    

    请注意,代理对(低代理 + 高代理一起)可以再次打印。单独的低代理是不可打印的。

    【讨论】:

    • 为什么说代理不可打印
    • 第一个代理不是。因此,如果他正在检查单个 WideChars,而不是字符串,则第一个代理不是“可打印的”。如果第一个代理项是字符串的两个元素之一,那么整个对当然可以打印。
    • UTF-16 是一种可变长度编码。以元素方式处理它是没有任何意义的。术语在这里非常重要。您错误地使用了“代码点”。两个代理对组合成一个代码点。
    • 我修改了答案。我知道 UTF-16 是一种可变长度编码。代理对(低 + 高代理一起)通常是可打印的,单独的低代理不是。
    • 您的编辑仍然使用错误的术语。要清楚 WideChar 值不是代码点。当您有代理对时,您需要两个 WideChar 值来定义一个代码点。好的,下一个编辑正确。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 2010-12-15
    • 2011-12-26
    • 1970-01-01
    • 2013-09-17
    相关资源
    最近更新 更多