C# 避免不必要的字符串替换
我有一个用于组装自动文件名的字符串模式。模式可能包含多个属性,例如:C# 避免不必要的字符串替换,c#,regex,placeholder,C#,Regex,Placeholder,我有一个用于组装自动文件名的字符串模式。模式可能包含多个属性,例如: [UserName] [ItemName] [ItemId] 等等。。。 当要创建名称时,我会获取属性的值,并在模式中替换它们以获得所需的名称。例如: var propertyDict = new Dictionary<string, string>() { ["[UserName]"] = "John Smit", ["[ItemName]&
[UserName]
[ItemName]
[ItemId]
等等。。。
当要创建名称时,我会获取属性的值,并在模式中替换它们以获得所需的名称。例如:
var propertyDict = new Dictionary<string, string>()
{
["[UserName]"] = "John Smit",
["[ItemName]"] = "Berry 47",
["[ItemId]"] = "123456",
};
var namingPattern = "[UserName] @ [ItemName] (id: [ItemId])";
// Expected result "John Smit @ Berry 47 (id: 123456)"
让我烦恼的是,用户选择了一个意外的名称,这可能会破坏逻辑。考虑以下情况:
var propertyDict = new Dictionary<string, string>()
{
["[UserName]"] = "[ItemName]", // Username matches with one of the placeholders
["[ItemName]"] = "Berry 47",
["[ItemId]"] = "123456",
};
var namingPattern = "[UserName] @ [ItemName] (id: [ItemId])";
// Expected result "[ItemName] @ Berry 47 (id: 123456)"
// Actual result "Berry 47 @ Berry 47 (id: 123456)"
我找到了一种通过使用正则表达式来解决这个问题的方法。我的想法是在进行任何字符串替换之前匹配所有可能的占位符\[[a-zA-Z]+\],然后通过首先检查匹配字符串的索引开始替换。然而,如果其他人将来不得不经历这种逻辑,那么这篇文章就太冗长和烦人了。有什么想法和建议吗?
提前谢谢 您可以使用Regex.Replace在一次过程中更新所有匹配项
这样,您就不会覆盖已进行的任何替换:
var namingPattern = "[UserName] @ [ItemName] (id: [ItemId])";
var regexPattern = string.Join("|", propertyDict.Keys.Select(Regex.Escape));
// \[UserName]|\[ItemName]|\[ItemId]
var fileName = Regex.Replace(namingPattern, regexPattern,
match => propertyDict[match.Value]);
为了避免必须使用Regex.Escape键,可以使用花括号:
var propertyDict = new Dictionary<string, string>()
{
["{UserName}"] = "John Smit",
["{ItemName}"] = "Berry 47",
["{ItemId}"] = "123456",
};
var namingPattern = "{UserName} @ {ItemName} (id: {ItemId})";
var regexPattern = string.Join("|", propertyDict.Keys);
// {UserName}|{ItemName}|{ItemId}
var fileName = Regex.Replace(namingPattern, regexPattern,
match => propertyDict[match.Value]);
您可以使用Regex.Replace在一次过程中更新所有匹配项
这样,您就不会覆盖已进行的任何替换:
var namingPattern = "[UserName] @ [ItemName] (id: [ItemId])";
var regexPattern = string.Join("|", propertyDict.Keys.Select(Regex.Escape));
// \[UserName]|\[ItemName]|\[ItemId]
var fileName = Regex.Replace(namingPattern, regexPattern,
match => propertyDict[match.Value]);
为了避免必须使用Regex.Escape键,可以使用花括号:
var propertyDict = new Dictionary<string, string>()
{
["{UserName}"] = "John Smit",
["{ItemName}"] = "Berry 47",
["{ItemId}"] = "123456",
};
var namingPattern = "{UserName} @ {ItemName} (id: {ItemId})";
var regexPattern = string.Join("|", propertyDict.Keys);
// {UserName}|{ItemName}|{ItemId}
var fileName = Regex.Replace(namingPattern, regexPattern,
match => propertyDict[match.Value]);
看@WiktorStribiżew它看起来正是我需要的东西!谢谢!我马上就去试试。看看@WiktorStribiżew它看起来正是我需要的东西!谢谢!我会立即尝试。模式[用户名]与[用户名]不匹配,但括号中的任何字符,例如U或r。应为string.Join |,propertyDict.SelectRegex。Escape@KlausGütter Yes,good spot,它也应该是propertyDict.Keys。模式[UserName]与[UserName]不匹配,但括号中的任何字符,例如U或r。应为string.Join |,propertyDict.SelectRegex。Escape@KlausGütter是的,这是个好地方,它也应该是propertyDict.Keys。