C# 中的正则表达式支持常见的 Unicode 类别,包括:
Nd - 数字:十进制数字
Nl - 数字:字母
否 - 编号:其他
N - 所有数字。包括类别 Nd、Nl 和 No。
为了测试一个正则表达式\p{N}可以包含类别 Nd、Nl 和 No 的断言,我编写了一个可以获取类别 N 的完整字符集的代码:
// Get all Unicode groups:
Dictionary<UnicodeCategory, IGrouping<UnicodeCategory, string>> charInfo = (
Enumerable.Range(0, 0x110000)
.Where (x => (x < 0x00D800 || x > 0x00DFFF))
.Select (Char.ConvertFromUtf32)
.GroupBy(s => Char.GetUnicodeCategory(s, 0))
.ToDictionary(g => g.Key)
);
// Get all number unicode groups:
string[] Nd = charInfo[UnicodeCategory.DecimalDigitNumber].ToArray();
string[] Nl = charInfo[UnicodeCategory.LetterNumber ].ToArray();
string[] No = charInfo[UnicodeCategory.OtherNumber ].ToArray();
string[] N = Nd.Union(Nl).Union(No).ToArray();
通过NUnit 测试中N的正则表达式运行生成的组字符集:
Regex.IsMatch(symbol, @"\p{N}+", RegexOptions.Multiline);
我得到的结果是数组 N 的一半字符没有通过方法的测试Regex.IsMatch()。
你能告诉我为什么正则表达式不能识别属于“数字”类别的字符\p{N}+吗?
简而言之...
Char对象的值是一个 16 位数字(序数)值。UTF-16 编码的字符串允许代理对由高位和低位通配符组成,每个都是类型的变量
char。如果我们计算这样一个字符的长度,str.Length它将返回2. 在英语中,这样的𝟬符号被定义为一个“代码点”,它由两个“代码单元”\ud835和组成\udfec。.NET 中的正则表达式不支持代理对,也就是说,它们在“代码单元”级别工作。这些对中的每一对都是正则表达式引擎的 16 位字节的正常序列。为了找到它们,您需要将这些序列指定为字符类中的范围。
这种正则表达式的演示,查找所有数字字符:
构建和测试模板
我已经声明了以下变量:
N然后我通过以下代码运行所有字符:调试文件在 MS Visual Studio 2017 中运行时包含 708 个字符,但在 ideone.com 上的 C# Mono 中仅包含 443 个字符。
接下来,您需要构建一个模板。为此,我们将带有键和值的列表按键分组,构建一系列值并将所有内容组合成一个正则表达式:
该方法
CreateRangesFromList看起来不是最好的,但它可以完成工作:检查帮助
bool check = testList.All(symbol => Regex.IsMatch(symbol, N_pattern));表明一切正常: