如何将字符串中每个$guid$替换为不同的Guid.NewGuid()值?
解决每个$guid$替换为不同Guid的问题
这个问题我之前也踩过坑!原来的string.Replace()方法之所以会把所有$guid$换成同一个Guid值,核心原因是:它会先计算好替换的目标值(也就是Guid.NewGuid().ToString()的结果),然后一次性把所有匹配的$guid$都替换成这个预先生成好的字符串,所以所有位置自然都是同一个Guid了。
要实现每个$guid$都替换成不同的新Guid,最简洁的方法是用Regex.Replace()的重载版本——它支持传入一个MatchEvaluator委托,每次匹配到目标字符串时都会执行这个委托,生成全新的替换值。
具体代码示例
首先看一下原代码的问题:
var myString = "$guid$! test $guid$, here another test string and then $guid$"; // 所有$guid$都会被替换成同一个Guid,不符合需求 var badResult = myString.Replace("$guid$", Guid.NewGuid().ToString());
下面是正确的实现:
using System.Text.RegularExpressions; var myString = "$guid$! test $guid$, here another test string and then $guid$"; // 每次匹配到$guid$时,生成一个新的Guid var goodResult = Regex.Replace(myString, @"\$guid\$", match => Guid.NewGuid().ToString());
细节说明
- 正则表达式里的
\$是对$的转义,因为$在正则语法中是表示字符串结尾的特殊字符,必须转义才能匹配字面量的$。 - 如果需要生成特定格式的Guid(比如不带连字符的格式),只需要修改
ToString()的参数即可:// 生成不带连字符的Guid(如"c9d4c053-538b-4565-9441-b1a86452667c"变成"c9d4c053538b45659441b1a86452667c") var formattedResult = Regex.Replace(myString, @"\$guid\$", match => Guid.NewGuid().ToString("N"));
备选方案(手动遍历替换)
如果不想用正则,也可以用StringBuilder手动循环查找并替换:
using System.Text; var myString = "$guid$! test $guid$, here another test string and then $guid$"; var sb = new StringBuilder(myString); var target = "$guid$"; int index = sb.ToString().IndexOf(target); while (index != -1) { sb.Replace(target, Guid.NewGuid().ToString(), index, target.Length); // 从下一个位置继续查找 index = sb.ToString().IndexOf(target, index + target.Length); } var manualResult = sb.ToString();
不过这种方法代码量更大,可读性不如正则方案,除非有特殊场景不适合用正则,否则更推荐第一种方法。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

