简体   繁体   English

用String.Replace或Regex.Replace替换特定数字

[英]Replacing specific numbers with String.Replace or Regex.Replace

Just having a little problem in attempting a string or regex replace on specific numbers in a string. 在尝试对字符串中的特定数字进行字符串或正则表达式替换时遇到一点问题。

For example, in the string 例如,在字符串中

@1 is having lunch with @10 @11

I would like to replace "@1", "@10" and "@11" with the respective values as indicated below. 我想将“ @ 1”,“ @ 10”和“ @ 11”分别替换为如下所示的值。

"@1" replace with "@bob"
"@10" replace with "@joe"
"@11" replace with "@sam"

So the final output would look like 所以最终输出看起来像

"@bob is having lunch with @joe @sam"

Attempts with 尝试

String.Replace("@1", "@bob")

results in the following 结果如下

@bob is having lunch with @bob0 @bob1

Any thoughts on what the solution might be? 对解决方案有何想法?

I would prefer more declarative way of doing this. 我希望采用更具声明性的方式来执行此操作。 What if there will be another replacements, for example @2 change to luke ? 如果还会有其他替换,例如将@2更改为luke怎么办? You will have to change the code (add another Replace call). 您将不得不更改代码(添加另一个“ Replace调用)。

My proposition with declarations of the replacements: 我对替代者声明的主张:

string input = "@1 is having lunch with @10 @11";
var rules = new Dictionary<string,string>() 
{
    { "@1", "@bob" },
    { "@10", "@joe" },
    { "@11", "@sam"}
};

string output = Regex.Replace(input, 
                              @"@\d+", 
                              match => rules[match.Value]);

Explanation: 说明:

Regular expression is searching for pattern @\\d+ which means @ followed by one or more digits. 正则表达式正在搜索模式@\\d+ ,这意味着@后跟一个或多个数字。 And replaces this match thanks to MatchEvaluator by the proper entry from the rules dictionary, where the key is the match value itself. MatchEvaluator通过rules字典中的正确条目替换此匹配项,其中键是匹配值本身。

Assuming all placeholder start with @ and contain only digits, you can use the Regex.Replace overload that accepts a MatchEvaluator delegate to pick the replacement value from a dictionary: 假设所有占位符以@开头并且仅包含数字,则可以使用Regex.Replace重载,该重载接受MatchEvaluator委托从字典中选择替换值:

var regex = new Regex(@"@\d+");

var dict = new Dictionary<string, string>
{
    {"@1","@bob"},
    {"@10","@joe"},
    {"@11","@sam"},
};

var input = "@1 is having lunch with @10 @11";
var result=regex.Replace(input, m => dict[m.Value]);

The result will be "@bob is having lunch with @joe @sam" 结果将是"@bob is having lunch with @joe @sam"

There are a few advantages compared to multiple String.Replace calls: 与多个String.Replace调用相比,有一些优点:

  1. The code is more concise, for an arbitrary number of placeholders 对于任意数量的占位符,代码更加简洁
  2. You avoid mistakes due to the order of the replacements (eg @11 must come before @1 ) 您可以避免由于替换顺序而引起的错误(例如@11必须在@1之前)
  3. It's faster because you don't need to search and replace the placeholders multiple times 速度更快,因为您无需多次搜索和替换占位符
  4. It doesn't create temporary strings for each parameter. 它不会为每个参数创建临时字符串。 This can be an issue for server applications because a large number of orphaned strings will put pressure on the garbage collector 对于服务器应用程序来说这可能是一个问题,因为大量的孤立字符串将对垃圾收集器施加压力

The reason for advantages 3-4 is that the regex will parse the input and create an internal representation that contains the indexes for any match. 之所以具有优势3-4,是因为正则表达式将解析输入并创建一个内部表示,其中包含任何匹配项的索引。 When the time comes to create the final string, it uses a StringBuilder to read characters from the original string but substitute the replacement values when a match is encountered. 当需要创建最终字符串时,它使用StringBuilder从原始字符串中读取字符,但是在遇到匹配项时替换替换值。

Start with the biggest (read longest) number like @11 and @10 first and then replace @1. 首先从最大(读取最长)的数字开始,例如@ 11和@ 10,然后替换@ 1。

string finalstring = mystring.Replace("@11", "@sam")
                             .Replace("@10", "@joe")
                             .Replace("@1", "@bob");

Make your regular expression look for the string @1_ 使您的正则表达式查找字符串@ 1_

The space after will ensure that it only gets the number @1. 后面的空格将确保仅得到数字@ 1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM