求助:使用.NET正则表达式匹配全Unicode数字失败
嘿,我来帮你捋捋这个踩过的坑——之前我也碰到过类似的情况,明明想着用Unicode类别匹配就能覆盖所有数字,结果总有漏网之鱼,太懂这种郁闷了😅
1. 别用\d,改用\p{N}匹配全类别Unicode数字
默认情况下,.NET的\d只认十进制数字(\p{Nd}类别)——就是我们熟悉的0-9,加上阿拉伯-Indic、印度数字这类十进制体系的字符,但像罗马数字(ⅠⅡⅢ)、圈数字(①②③)、分数(¼½¾)这些属于\p{Nl}(字母数字)或\p{No}(其他数字)的字符,\d是抓不到的。
如果要覆盖所有Unicode体系的数字,直接用\p{N}就行,它会匹配所有Unicode数字类别(Nd、Nl、No)的字符。比如试试这段测试代码:
var testStr = "123 ٤٥٦ ७८९ ⅠⅡⅢ ①②③ ¼½¾"; var regex = new Regex(@"\p{N}+"); foreach (var match in regex.Matches(testStr)) { Console.WriteLine($"捕获到:{match.Value}"); }
运行后应该能把所有类型的数字序列都抓出来。
2. 确保UTF-8文件解码没出错
你提到字符串来自UTF-8编码的文件,这一步一定要注意!如果读取时用了默认的File.ReadAllText(path)(自动检测编码偶尔会翻车),或者误用了ASCII编码,字符会变成乱码,自然没法被正则识别。
正确的读取方式要显式指定UTF-8:
var content = File.ReadAllText("你的文件路径", Encoding.UTF8);
如果文件带BOM,Encoding.UTF8会自动处理;要是文件无BOM,也可以用new UTF8Encoding(false)来忽略BOM,根据你的文件情况选就行。
3. 排查未识别数字的Unicode属性
要是还有部分数字没被捕获,那得先确认这些字符到底算不算Unicode数字。有些看起来像数字的字符,其实属于其他类别(比如特殊符号或字母)。
你可以用这段代码查看单个字符的Unicode类别:
char targetChar = '你要测试的字符'; var category = Char.GetUnicodeCategory(targetChar); Console.WriteLine($"字符{targetChar}的Unicode类别:{category}");
如果返回的是DecimalDigitNumber、LetterNumber或OtherNumber,那\p{N}肯定能匹配;要是其他类别,那它本来就不属于Unicode数字体系,自然抓不到。
4. 注意正则选项的影响
如果你开启了RegexOptions.ECMAScript,\d会被限制为仅匹配ASCII的0-9,但\p{N}不受这个选项影响,所以只要用\p{N}就不用怕这个问题。
内容的提问来源于stack exchange,提问作者wtfowler

