[英]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++);
}
是否指定replacementIndex
或replacementIndex++
都沒有關系,這很有意義,但我只想將代碼與找到的答案盡可能地匹配。
輸出看起來像這樣:
<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.