正则表达式在组之间替换

时间:2017-07-06 11:18:52

标签: c# regex regex-group

所以我在C#中有以下regex.replace:

Regex.Replace(inputString, @"^([^,]*,){5}(.*)", @"$1somestring,$2");

其中5是代码中的变量号,但这并不是真正相关的,因为在执行时它总是有一个设定值(例如5)。与somestring,相同。

基本上我想在两组之间输入somestring,。输出适用于somestring,$2,但$1仅打印为$1。所以说无论(.*)抓取= "2, a, f2",无论$1somestring,2,a,f2是什么,我得出的结果都是$1。这是因为重复组功能{5}?如果是这样,我如何获取重复的集合并将其放在我现在$1的位置?

编辑:我知道第一组也能正确捕获。我使用此正则表达式获取somestring,的内容:

Regex.Match(line, @"^([^,]*,){5}([0-9]+\.[0-9]+),.*");

第一部分与替换正则表达式中的第一部分相同,并且它工作正常,因此不应该是一个问题(并且它们都在同一个字符串上使用)。

Edit2:

好的,我会尝试解释更多的过程,因为有人说这很难理解。我有三个变量,line我使用的字符串,以及latIndexlonIndex这些只是整数(告诉我在哪个,我找的两个双打位于)。我有以下两场比赛:

var latitudeMatch = Regex.Match(line, @"^([^,]*,){" + latIndex + @"}([0-9]+\.[0-9]+),.*");
var longitudeMatch = Regex.Match(line, @"^([^,]*,){" + lonIndex + @"}([0-9]+\.[0-9]+),.*");
然后我抓住了双打:

var latitude = latitudeMatch.Groups[2].Value;
var longitude = longitudeMatch.Groups[2].Value;

我使用这些双打来从Web API获取字符串,我将其存储在名为veiRef的变量中。然后我想在双打之后插入这些,使用下面的代码(在lat或lon之后插入,取决于最后出现的那个):

if (latIndex > lonIndex)
{
    line = Regex.Replace(line, @"^([^,]*,){" + (latIndex+1) + @"}(.*)",$@"$1{veiRef},$2");
}
else
{
    line = Regex.Replace(line, @"^([^,]*,){" + (lonIndex + 1) + @"}(.*)", $@"$1{veiRef},$2");
}

但是,这会产生一个字符串line,它不会在它之前插入$ 1的内容($ 2正常工作)。

2 个答案:

答案 0 :(得分:3)

您在模式的开头有一个重复捕获组,您需要将其转换为非捕获组并使用捕获组进行换行。然后,您可以使用$1反向引用访问匹配的整个部分。

var line = "a, s, f, double, double, 12, sd, 1";
var latIndex = 5;
var pat = $@"^((?:[^,]*,){{{latIndex+1}}})(.*)";
// Console.WriteLine(pat); // => ^((?:[^,]*,){6})(.*)
var veiRef = "str";
line = Regex.Replace(line, pat, $"$^((?:[^,]*,){6})(.*){veiRef.Replace("$","$$")}$2");
Console.WriteLine(line); // => a, s, f, double, double, 12,str sd, 1

请参阅C# demo

模式 - ((?:[^,]*,){6}) - 现在在^之后包含$1,现在这是$在找到匹配后所持有的内容。

由于您的替换字符串是动态的,因此您需要确保内部的任何.Replace("$","$$")加倍(因此,${1})并且第一个反向引用是明确的,因此它应该看起来像{{1} (无论veiRef是否以数字开头,它都会起作用。)

详细替换字符串:

  • 这是一个插值字符串文字...
  • $" - 内插字符串文字的声明(开始)
  • $${1} - 文字{字符串(}{veiRef.Replace("$","$$")}必须加倍才能表示文字符号)
  • {...} - 插值字符串文字中的一段C#代码(我们用单$2分隔允许代码的此部分)
  • $2 - 文字"字符串
  • file://* - 插值字符串文字的结尾。

答案 1 :(得分:0)

在重复捕获组周围添加一个额外的组似乎为您提供的示例提供了所需的输出。

Regex.Replace("a, s, f, double, double, 12, sd, 1", @"^(([^,]*,){5})(.*)", @"$1somestring,$3");

我不是RegEx的专家,有人可以解释它比我更好,但是: -

组1是5个重复捕获组的集合 第2组是最后一个重复捕获组 第3组是5个重复捕获组之后的文本。