簡體   English   中英

替換字符串中的第N個正則表達式匹配

[英]Replace Nth regex match occurrence in string

我知道在SO上有很多這樣的問題,但我找不到解釋他們如何實現模式以返回第N個匹配的問題。 我看到的所有答案只是給OP提供了最少解釋的代碼。

我所知道的是,你需要在模式中實現這個{X} ,其中X是你想要返回的數字。

所以我試圖匹配兩個chars之間的string ,我似乎已經能夠使其工作。

要測試的字符串看起來像這樣,

"=StringOne&=StringTwo&=StringThree&=StringFour&"

"[^/=]+(?=&)"

再次,在盡可能多地閱讀之后,這個模式也將返回所有匹配,

[^/=]+(?=&){1}

由於{1}是默認值,因此在上述模式中是多余的。 但我不能這樣做,

[^/=]+(?=&){2}

因為它不會像我期待的那樣返回第3場比賽。

那么有人可以把我推向正確的方向並解釋如何獲得所需的模式以找到所需的匹配事件嗎?

純正的正則表達式是可行的,但如果你的模式很復雜,那么效率並不高。

var s = "=StringOne&=StringTwo&=StringThree&=StringFour&";
var idx = 2;     // Replace this occurrence
var result = Regex.Replace(s, $@"^(=(?:[^=&]+&=){{{idx-1}}})[^=&]+", "${1}REPLACED");
Console.WriteLine(result); // => =StringOne&=REPLACED&=StringThree&=StringFour&

請參閱此C#演示正則表達式演示

在此輸入圖像描述

正則表達式細節

  • ^ - 字符串的開頭
  • (=(?:[^=&]+&=){1}) - 第1組捕獲:
    • = - a =符號
    • (?:[^=&]+&=){1} - 1次出現(這個數字是動態生成的)
    • [^=&]+ - 除=&之外的1個或多個字符( 注意 ,如果字符串可能包含=& ,則用.*?替換它並將RegexOptions.Singleline選項傳遞給正則表達式編譯器更安全)
    • &= - a &=子字符串。
  • [^=&]+ - 除=&之外的1個或多個字符

替換模式中的${1}將組1的內容插回到結果字符串中。

作為替代方案,我可以建議在每次匹配時引入計數器和增量,並且只有在計數器等於您指定的匹配項時才替換該計數器。

采用

var s = "=StringOne&=StringTwo&=StringThree&=StringFour&";
var idx_to_replace = 2; // Replace this occurrence
var cnt = 0;            // Counter
var result = Regex.Replace(s, "[^=]+(?=&)", m => {  // Match evaluator
        cnt++; return cnt == idx_to_replace ? "REPLACED" : m.Value; });
Console.WriteLine(result); 
// => =StringOne&=REPLACED&=StringThree&=StringFour&

請參閱C#演示

cntRegex.Replace內的匹配賦值器內遞增,並為m分配當前的Match對象。 cnt等於idx_to_replace時,發生替換,否則,粘貼整個匹配(使用m.Value )。

另一種方法是迭代匹配,一旦找到第N個匹配,通過在匹配之前將字符串拆分為部分並在匹配完成替換之后將其替換為循環來替換它:

var s = "=StringOne&=StringTwo&=StringThree&=StringFour&";
var idx_to_replace = 2;     // Replace this occurrence
var cnt = 0;                // Counter
var result = string.Empty;  // Final result variable
var rx = "[^=]+(?=&)";      // Pattern
for (var m=Regex.Match(s, rx); m.Success; m = m.NextMatch())
{
    cnt++;
    if (cnt == idx_to_replace) {
        result = $"{s.Substring(0, m.Index)}REPLACED{s.Substring(m.Index+m.Length)}";
        break;
    }
}
Console.WriteLine(result); // => =StringOne&=REPLACED&=StringThree&=StringFour&

另一個C#演示

這可能會更快,因為引擎不必找到所有匹配項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM