编辑:此示例使用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*
个代码,只替换第二个代码&#34;。
我以为我找到了答案: How do I replace a specific occurrence of a string in a string?
不幸的是,结果并不是我想要的。这是我的示例代码:
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
。
从几个月前开始,我在理解正则表达式匹配方面变得越来越好,但我对正则表达式的数学评估和组合并不熟悉;我想这就是我可能需要的东西。
您能否推荐我如何修复代码,以便替换正则表达式匹配的特定索引?
答案 0 :(得分:0)
抱歉无法用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>');
在这种特定情况下基本上会得到相同的结果。
答案 1 :(得分:0)
使用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));
}
答案 2 :(得分:0)
我为此忙碌了整整一天。当然,提出这个问题有时会让创意变得流动,所以这就是我提出的解决方案。它使用MatchCollection,然后使用字符串构建器插入字符串。字符串生成器可能有点过分,但它可以工作: - )
replacementIndex定义要插入文本的匹配项。在我的例子中,正则表达式找到三个实例并修改找到的索引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);
}