模式中包含 \Uxxxxxxxx 字符的 C# 正则表达式

发布于 2024-07-10 10:10:24 字数 285 浏览 14 评论 0原文

Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" ) 

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

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

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

Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" ) 

Throws: System.ArgumentException: parsing "[-]" - [x-y] range in reverse order.

Looking at the hex values for \U00010000 and \U0010FFF I get: 0xd800 0xdc00 for the first character and 0xdbff 0xdfff for the second.

So I guess I have really have one problem. Why are the Unicode characters formed with \U split into two chars in the string?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独﹏钓一江月 2024-07-17 10:10:24

它们是代理对。 查看这些值 - 它们超过 65535。字符只是一个 16 位值。 如何用 16 位表示 65536?

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

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

They're surrogate pairs. Look at the values - they're over 65535. A char is only a 16 bit value. How would you expression 65536 in only 16 bits?

Unfortunately it's not clear from the documentation how (or whether) the regular expression engine in .NET copes with characters which aren't in the basic multilingual plane. (The \uxxxx pattern in the regular expression documentation only covers 0-65535, just like \uxxxx as a C# escape sequence.)

Is your real regular expression bigger, or are you actually just trying to see if there are any non-BMP characters in there?

ゃ人海孤独症 2024-07-17 10:10:24

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

阅读和操作起来比较困难,而且不太灵活,但仍然适合作为解决方法。

To workaround such things with .Net regex engine, I'm using following trick:
"[\U010000-\U10FFFF]" is replaced with [\uD800-\uDBFF][\uDC00-\uDFFF]
The idea behind this is that as .Net regexes handle code units instead of code points, we're providing it with surrogate ranges as regular characters. It's also possible to specify more narrow ranges by operating with edges, e.g.: [\U011DEF-\U013E07] is same as (?:\uD807[\uDDEF-\uDFFF])|(?:[\uD808-\uD80E][\uDC00-\uDFFF])|(?:\uD80F[\uDC00-uDE07])

It's harder to read and operate with, and it's not that flexible, but still fits as workaround.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文