簡體   English   中英

替換正則表達式匹配中特定出現的文本

[英]Replace specific occurrence of text in a Regex Match

編輯:此示例使用html,但我需要這種類型的方案來處理其他類型的字符串。 請將此作為正則表達式問題而不是html問題閱讀。

假設我有一個像這樣的字符串:

<h1>Hello</h1><h2>World</h2><h3>!</h3>

我可能需要將文本替換為這些標題標簽中的任何一個,但讓我們使用此示例,在此示例中,我只想將<h2>修改為如下所示:

<h1>Hello</h1><div id="h2div"></div><h2>World</h2><h3>!</h3>

由於可能需要替換任何標題,因此我僅使用正則表達式搜索<h* 現在,我希望我的代碼說“您發現的所有<h*標簽中,僅替換第二個”。

我以為自己在這里找到了答案: 如何替換字符串中特定出現的字符串?

不幸的是,結果不是我想要的。 這是我的示例代碼:

    private void button1_Click(object sender, EventArgs e)
    {
        //sample html file string:
        var htmlText = "<h1>Hello</h1><h2>World</h2><h3>!</h3>";

        //this text should replace <h2 with <div id="h2div"></div><h2"
        var replacementString = "<div id=\"" + "h2div" + "\"" + "</div>" + "<h2";
        int replacementIndex = 1; //only replace the second occurence found by regex.

        //find ALL occurrences of <h1 through <h6 in the file, but only replace <h2.
        htmlText = Regex.Replace(htmlText, "<h([1-6])", m => replacementString + replacementIndex++);

    }

是否指定replacementIndexreplacementIndex++都沒有關系,這很有意義,但我只想將代碼與找到的答案盡可能地匹配。

輸出看起來像這樣:

<div id="h2div"></div><h21>Hello</h1><div id="h2div"></div><h22>World</h2><div id="h2div"></div><h23>!</h3>

這里有很多事情不應該發生。 首先,應該只創建一個<div>標簽,而不是三個。 其次,僅替換<h標記而不是<h2 ,所以現在我們以<h21<h22<h23

從幾個月前開始,我對regex匹配的理解越來越好,但是我真的不熟悉regex匹配評估器和組。 我想這可能是我在這里需要的。

您能推薦我如何修復代碼,以便替換正則表達式匹配項的特定索引嗎?

抱歉,無法使用C#回答,但答案應該非常相似。 對於您的特殊情況,您的JavaScript String.prototype.replace() regexp屬性是/(<h1.+?\\/h1>)/ ,替換屬性是"$1<div id="h2div">"

var str = "<h1>Hello</h1><h2>World</h2><h3>!</h3>",
 repStr = str.replace(/(<h1.+?\/h1>)/,'$1<div id="h2div"></div>');

console.log(repStr) // "<h1>Hello</h1><div id="h2div"></div><h2>World</h2><h3>!</h3>"

或者,如果您不想使用捕獲組,您仍然可以喜歡

var repStr = str.replace(/<h1.+?\/h1>/,'$&<div id="h2div"></div>');

在這種特定情況下,這基本上會產生相同的結果。

使用MatchEvaluator?

private static int count = 0;
    static string CapText(Match m)
    {
        count++;

        if (count == 2)
        {
            return "<div id=\"h2div\"></div>" + m.Value;
        }

        return m.Value;
    }

private void button1_Click()
{
    var htmlText = "<h1>Hello</h1><h2>World</h2><h3>!</h3>";
    Regex rx = new Regex(@"<h([1-6])");
    var result = rx.Replace(htmlText, new MatchEvaluator(ClassOfThis.CapText));
}

我為此奮斗了一整天。 自然地,提出問題有時會激發創意,因此這就是我想出的解決方案。 它使用MatchCollection,然后使用字符串生成器插入字符串。 字符串生成器對此可能有些過分,但它可以工作:-)

replaceIndex定義您要插入文本的匹配項。 就我而言,正則表達式找到三個實例並修改找到的索引1。從那里,我得到起始字符串索引,並使用子字符串插入文本。 這只是一個按鈕的測試代碼,以證明其功能。

    private void button1_Click(object sender, EventArgs e)
    {
        //sample text.
        var htmlText = "<h1>Hello</h1><h2>World</h2><h3>!</h3>";

        //the string builder will handle replacing the text.
        var stringBuilder = new StringBuilder(htmlText);

        //build the replacement text.
        var replacementString = "<div id=\"" + "h2div" + "\">" + "</div>";
        int replacementIndex = 1; //only replace the second occurence found by regex (zero-indexed).

        //find ALL occurrences of <h1 through <h6 in the file, but only replace <h2.
        var pattern = "<h([1-6])";
        MatchCollection matches = Regex.Matches(htmlText, pattern); //get all the matches.
        int startIndex = matches[replacementIndex].Index; //get the starting string index for the match.

        //insert the required text just before the found match.
        stringBuilder.Insert(startIndex, replacementString);

        //copy text to clipboard and display it on screen.
        htmlText = stringBuilder.ToString();
        System.Windows.Forms.Clipboard.SetText(htmlText);
        MessageBox.Show(htmlText);
    }

暫無
暫無

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

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