regex.replace 是替换字符串中数字最直接高效的方法,推荐使用 regex.replace(input, @"\d", "*");若需处理全角或阿拉伯数字,应扩展字符集而非盲目用 \p{nd}。

用 Regex.Replace 替换所有数字最直接
想把字符串里每个数字(0–9)全换成别的字符,比如星号或空,Regex.Replace 是最稳的选择。它不依赖循环,语义清晰,且能处理连续数字、开头结尾数字等边界情况。
常见错误是手写 for 循环 + string.Replace,结果只替换了第一个“0”或“1”,因为 string.Replace 是按字面值替换,不是按模式。
-
Regex.Replace(input, @"d", "*")—— 替换单个数字为* -
Regex.Replace(input, @"d+", "X")—— 替换连续数字串为一个X(比如"ab123cd45"→"abXcdX") - 注意
d在 C# 字符串里要加@前缀,否则得写成"\d",漏掉容易报错ArgumentException: parsing " - 如果输入可能为
null,先判空,Regex.Replace(null, ...)会直接返回null,不抛异常,但后续使用容易 NRE
不用正则?char.IsDigit 配合 StringBuilder 更可控
正则虽快,但如果你需要区分数字和其他 Unicode 数字符号(比如阿拉伯数字、罗马数字)、或想在替换时动态决定替换内容(比如偶数变 A、奇数变 B),就得手动遍历。
别用 string + string 拼接,大量替换时性能断崖式下跌;也别用 input.Select(...).ToArray() 再 new string(),堆分配多、GC 压力大。
- 用
StringBuilder预估容量(比如new StringBuilder(input.Length)) - 遍历每个
char,用char.IsDigit(c)判断,不是int.TryParse或正则——后者开销大且没必要 -
char.IsDigit只认 ASCII 0–9,不匹配全角数字或带符号数字(如①、⁻1),这点常被忽略 - 示例:把数字转为对应字母(0→A, 1→B…):
sb.Append((char)('A' + c - '0')),但要先确保c是'0'到'9'
RegexOptions.Compiled 不是默认选项,别乱加
有人一看到“正则慢”,就加 RegexOptions.Compiled,结果发现首次调用更慢,还占更多内存。它只在同一个正则模式重复调用上百次以上时才值得用。
日常替换所有数字这种简单场景,不加选项就是最优解——Regex.Replace(input, @"d", "*") 底层已做缓存,比手动编译更快更轻量。
- 加了
Compiled后,正则表达式会被 JIT 编译成 IL,启动慢、内存占用高,且无法热更新 - 如果正则模式来自配置或用户输入(比如替换规则可配),绝对不能用
Compiled,有安全和稳定性风险 - 真要优化高频正则,优先考虑预编译静态
Regex实例:private static readonly Regex DigitRegex = new(@"d");,然后复用DigitRegex.Replace(...)
中文混排时小心全角数字和 Unicode 数字字符
d 默认只匹配 ASCII 数字(U+0030–U+0039),对中文全角数字(U+FF10–U+FF19)、阿拉伯-印度数字(U+0660–U+0669)完全无效。用户粘贴的文本里常混着这些,一替换就漏掉。
如果业务要求“所有人类可读的数字字符都得换”,就得扩展匹配范围,但别盲目用 p{Nd}——它太宽,会把罗马数字、上标数字甚至某些货币符号也卷进来。
- 明确需求:只要常见多语言十进制数字?用
[duFF10-uFF19u0660-u0669](ASCII + 全角 + 阿拉伯-印度) - 测试用例至少包括:
"abc123def٤٥٦ghi"(全角+阿拉伯数字),看是否全被替换 -
p{Nd}匹配所有 Unicode 十进制数字字符,共几百个码位,性能略降,且可能误伤(比如"⁰¹²"上标数字是否该换?得看产品定义)
真正麻烦的是混合场景:用户输入不可控,又要求“看起来像数字的都得换”。这时候光靠正则不够,得结合语义判断,或者接受漏掉极少数边缘字符——毕竟不是所有“数字感”的符号都属于 Number, Decimal Digit 类别。











