Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" )
抛出:System.ArgumentException:以相反的顺序解析“[ - ]” - [x-y]范围。
查看\ U00010000和\ U0010FFF的十六进制值我得到:第一个字符为0xd800 0xdc00,第二个字符为0xdbff 0xdfff。
所以我想我确实有一个问题。为什么用\ U形成的Unicode字符在字符串中分成两个字符?
答案 0 :(得分:10)
他们是surrogate pairs。查看值 - 它们超过65535. char只有16位值。你如何只用16位表达65536?
不幸的是,从文档中不清楚.NET中的正则表达式引擎如何(或是否)处理不在基本多语言平面中的字符。 (正则表达式文档中的\ uxxxx模式仅涵盖0-65535,就像\ uxxxx作为C#转义序列一样。)
你真正的正则表达式是否更大,或者你实际上只是想看看那里是否有任何非BMP字符?
答案 1 :(得分:4)
要使用.Net正则表达式引擎解决此类问题,我正在使用以下技巧:
"[\U010000-\U10FFFF]"
已替换为[\uD800-\uDBFF][\uDC00-\uDFFF]
这背后的想法是,当.Net正则表达式处理代码单元而不是代码点时,我们为它提供代理范围作为常规字符。通过边缘操作也可以指定更窄的范围,例如:[\U011DEF-\U013E07]
与(?:\uD807[\uDDEF-\uDFFF])|(?:[\uD808-\uD80E][\uDC00-\uDFFF])|(?:\uD80F[\uDC00-uDE07])
相同
阅读和操作起来比较困难,并不是那么灵活,但仍适合作为解决方法。
答案 2 :(得分:1)
@Jon Skeet
所以你告诉我的是,没有办法在.net中使用正则表达式工具来匹配utf-16范围之外的字符?
完整的正则表达式是:
^(\u0009|[\u0020-\u007E]|\u0085|[\u00A0-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF])+$
我正在尝试检查字符串是否只包含yaml文档定义为可打印的Unicode字符的内容。