Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 避免不必要的字符串替换_C#_Regex_Placeholder - Fatal编程技术网

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。