匹配文本模板中的多个字符串

时间:2018-04-12 06:51:25

标签: c# regex

对于有经验的Regex专家来说,这可能是一个微不足道的问题,但在搜索了几个小时后,我不得不承认我似乎不知道正确的搜索条件。

我隐约记得在某些搜索/替换目标正则表达式引擎(文本编辑器)中,可以为子模式匹配定义变量,以便在替换字符串中重新排列它们。像(伪代码)

的东西
string input = "name: john, profession: lumberjack";
string pattern = @"[a-z]*: %1=([a-z]*), [a-z]*: %2=([a-z]*)";
string replacement = @"customer %1 is a %2";
string result = Regex.Replace(input ,pattern ,replacement);

结果应该假设“顾客约翰是一名伐木工人”。我不知道在C#中是否可行,但我想做的是获取在数组中返回的子模式匹配,如(再次伪代码)

string[] subMatches = Regex.MultiMatch(input ,pattern);

其中subMatches[0]=="john"subMatches[1]=="lumberjack"

我知道我可以在逐个匹配的情况下使用lookaround assertions进行操作,然后在循环中构造数组并检查所有子模式是否匹配。

但是我还想要一个单行表达式(比如上面的第二个代码块)吗?

2 个答案:

答案 0 :(得分:2)

您可以使用带有捕获组的简单正则表达式和带有替换后向引用(占位符)的Regex.Replace来插入子匹配项:

var result = Regex.Replace(s, @"[a-z]+:\s*([a-z]+),\s*[a-z]+:\s*([a-z]+)", "customer $1 is a $2");
// => customer john is a lumberjack

请参阅regex demo

模式详情

  • [a-z]+ - 1个小写ASCII字母(要匹配任何字母,使用\p{L}并使用任何“字”字符,请使用\w代替[a-z])< / LI>
  • :\s* - 冒号后跟0 +空格字符
  • ([a-z]+) - 第1组(引用替换模式中使用$1):1 + ASCII小写字母(参见上面的注释)
  • ,\s* - 逗号和0 +空格字符
  • [a-z]+:\s* - 1 + ASCII小写字母,:和0+空白字符
  • ([a-z]+) - 第2组(引用替换模式中使用$2):1 + ASCII小写字母(请参阅上面的注释)

答案 1 :(得分:0)

感谢你让我朝着正确的方向前进,向团队迈进。关于替换,Wiktor回答了问题的第一部分。至于第二部分(让字符串数组中的组匹配),我提出了以下解决方案

string input = "name: john, profession: lumberjack";
string pattern = @"[a-z]+:\s*([a-z]+),\s*[a-z]+:\s*([a-z]+)";

string[] subMatches = Regex.Match(input, pattern).Groups
    .Cast<Group>().Skip(1).Select(x => x.Value).ToArray();

foreach (string s in subMatches)
{
    Console.WriteLine(s);
}

输出:

  

约翰

     

伐木

演员阵容是必要的,因为Linq似乎没有准备好处理GroupCollections。跳过是必要的,因为第一组匹配是整个模式,而GroupCollection中的后续项是各组的匹配。