【问题标题】:C# Regular Expressions with \Uxxxxxxxx characters in the pattern模式中带有 \Uxxxxxxxx 字符的 C# 正则表达式
【发布时间】:2008-12-12 20:18:26
【问题描述】:
Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" ) 

抛出:System.ArgumentException:以相反的顺序解析“[-]” - [x-y] 范围。

查看 \U00010000 和 \U0010FFF 的十六进制值,我得到:第一个字符为 0xd800 0xdc00,第二个字符为 0xdbff 0xdfff。

所以我想我真的有一个问题。为什么用 \U 组成的 Unicode 字符在字符串中分成两个字符?

【问题讨论】:

    标签: c# regex unicode astral-plane


    【解决方案1】:

    他们是surrogate pairs。看看这些值——它们超过了 65535。一个字符只是一个 16 位的值。你会如何用 16 位来表达 65536?

    不幸的是,从文档中并不清楚 .NET 中的正则表达式引擎如何(或是否)处理不在基本多语言平面中的字符。 (正则表达式文档中的 \uxxxx 模式仅涵盖 0-65535,就像将 \uxxxx 作为 C# 转义序列一样。)

    你真正的正则表达式更大,还是你实际上只是想看看那里是否有任何非 BMP 字符?

    【讨论】:

    • 其实你是对的。根据我的发现,\u 只支持 4 个十六进制数字(正好 4 个,不多不少),\uFFFF 是最大值。我删除了我的“解决方案”,因为虽然它不会产生错误,但它似乎不是一个有效的 unicode 正则表达式。我仍然认为 \ 需要被转义。
    • 如果没有 @ 你需要转义 \ 如果 \UFFFF 是正则表达式语法(如 \d 表示 [0-9]),但它是字符串文字语法(如 \n 表示 new-行字符)。
    • 这很不幸 - 许多现代表情符号都属于这一类。
    • @damian:完全有可能在这篇文章发布后的 7 年里,正则表达式引擎在这方面变得更好了。请注意,我正在回答的问题只是直接关于为什么\Uxxxxxxxx 以两个字符结尾......“处理正则表达式”部分有些分开。如果您目前面临这个问题,您可能想问一个新问题。
    • 自发布以来 12 年,但仍然不受支持。
    【解决方案2】:

    要使用 .Net 正则表达式引擎解决此类问题,我使用了以下技巧: "[\U010000-\U10FFFF]" 替换为 [\uD800-\uDBFF][\uDC00-\uDFFF] 这背后的想法是,当 .Net 正则表达式处理代码单元而不是代码点时,我们为它提供了作为常规字符的代理范围。也可以通过边缘操作来指定更窄的范围,例如:[\U011DEF-\U013E07](?:\uD807[\uDDEF-\uDFFF])|(?:[\uD808-\uD80E][\uDC00-\uDFFF])|(?:\uD80F[\uDC00-uDE07]) 相同

    它更难阅读和操作,也不是那么灵活,但仍然适合作为解决方法。

    【讨论】:

      【解决方案3】:

      @乔恩斯基特

      所以你告诉我的是,没有办法使用 .net 中的正则表达式工具来匹配 utf-16 范围之外的字符?

      完整的正则表达式是:

      ^(\u0009|[\u0020-\u007E]|\u0085|[\u00A0-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF])+$
      

      我正在尝试检查字符串是否仅包含 yaml 文档定义为可打印 Unicode 字符的内容。

      【讨论】:

      • 我不知道,很遗憾。我在文档中看不到任何关于如何将 .NET 正则表达式引擎与基本多语言平面之外的字符一起使用的内容。但是,完全不使用正则表达式来实现您想要的东西可能并不难。
      • 或者,您可以使用构成代理对的 16 位代码点:[\ud800–\udfff]。至少值得一试……
      • (此时,您可以将多个范围组合在一起 - 后面的位只是 [\u00a0-\ufffd]。)
      • .NET 正则表达式引擎在 UTF-16 代码点上运行,而不是 Unicode 字符;见code.logos.com/blog/2008/07/…。我已经就这个问题提交了一个 Connect 错误:connect.microsoft.com/VisualStudio/feedback/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2015-11-28
      • 1970-01-01
      • 2014-09-28
      相关资源
      最近更新 更多