C# 尝试替换HTML文档中的字符串并添加额外字符

C# 尝试替换HTML文档中的字符串并添加额外字符,c#,html,regex,replace,C#,Html,Regex,Replace,我要做的是打开一个文件,搜索“searchText”。我想用一个新的链接替换文件中的所有实例,实际上这只是一个带有achor链接的文件名,所以它不会打开javascript,而是转到页面中的另一个点 到目前为止,我得到的是: private void writeNotes(){ StreamReader reader = new StreamReader(openFileDialog1.FileName); string content = reader.Read

我要做的是打开一个文件,搜索“searchText”。我想用一个新的链接替换文件中的所有实例,实际上这只是一个带有achor链接的文件名,所以它不会打开javascript,而是转到页面中的另一个点

到目前为止,我得到的是:

private void writeNotes(){
        StreamReader reader = new StreamReader(openFileDialog1.FileName);
        string content = reader.ReadToEnd();

        reader.Close();

        string fileName = openFileDialog1.SafeFileName;
        string searchText = "<a class=\"x-fn\" href=\"javascript:void(0);\">";
        string replaceText = "<a class=\"x-fn\" href=\"" + fileName + "#fn" + "\">";

        content = Regex.Replace(content, searchText, replaceText);

        StreamWriter writer = new StreamWriter(openFileDialog1.FileName);
        writer.Write(content);
        writer.Close();
private void writeNotes(){
StreamReader=新的StreamReader(openFileDialog1.FileName);
字符串内容=reader.ReadToEnd();
reader.Close();
字符串文件名=openFileDialog1.SafeFileName;
字符串searchText=“”;
字符串replaceText=“”;
content=Regex.Replace(content、searchText、replaceText);
StreamWriter writer=新的StreamWriter(openFileDialog1.FileName);
作者:写(内容);
writer.Close();
但是,在写入和关闭之后……我打开文件,没有做任何更改。除此之外,我要做的是为每个替换实例添加一个在“#fn”之后计数的数字。因此,基本上,每次我用另一个替换javascript链接时,我希望它是:

<a class="x-fn" href="fileName#fn1">

然后,当我替换javascript的第二个实例时,它会

<a class="x-fn" href="fileName#fn2">

等等


我想我必须计算javascript出现的次数,替换它,并使用for循环在所有新链接中迭代,并在末尾添加#fn(n)?

您的问题是您有元字符(在本例中,“void(0)”中的打开和关闭参数)。这不是表示文字打开和关闭参数,而是创建一个正则表达式组,这将导致匹配失败。如果使用反斜杠转义参数,它将按预期工作

但是,由于您只是匹配字符串文字,因此根本不需要使用正则表达式;使用
string.Replace
会更快

至于你问题的第二部分,这有点棘手。据我所知,没有简单的方法可以做到这一点,因此最好的方法是在输入中查找搜索文本,然后在进行过程中建立一个
StringBuilder
,增加一个计数变量。在下面的示例中,“the”一词被替换为“(0)”和“(1)”为了简单起见,但您可以很容易地将其适应您的问题

var content = "the quick brown fox jumped over the lazy dog";
var searchText = "the";
var sb = new StringBuilder();
var idx = -1; // will hold the index of our search text
var uncopiedIdx = 0; // the start index of what hasn't been copied yet
var replacementCount = 0;
while( (idx = content.IndexOf( searchText, idx+1 )) != -1 ) {
    // copy everything leading up to our search text
    sb.Append( content.Substring( uncopiedIdx, idx-uncopiedIdx ) );
    // copy the replacement text, with the replacement count
    var replacement = "(" + replacementCount++ + ")";
    sb.Append( replacement );
    // skip over the search text
    uncopiedIdx = idx + searchText.Length;
}
// copy everything after the last match
sb.Append( content.Substring( uncopiedIdx ) );

您的问题是您有元字符(在本例中为“void(0)”中的打开和关闭参数)。这不是表示文字打开和关闭参数,而是创建一个正则表达式组,这会导致匹配失败。如果使用反斜杠转义参数,它将按预期工作

但是,由于您只是匹配字符串文字,因此根本不需要使用正则表达式;使用
string.Replace
会更快

至于你问题的第二部分,这有点棘手。据我所知,没有简单的方法可以做到这一点,因此最好的方法是在输入中查找搜索文本,然后在进行过程中建立一个
StringBuilder
,增加一个计数变量。在下面的示例中,“the”一词被替换为“(0)”和“(1)”为了简单起见,但您可以很容易地将其适应您的问题

var content = "the quick brown fox jumped over the lazy dog";
var searchText = "the";
var sb = new StringBuilder();
var idx = -1; // will hold the index of our search text
var uncopiedIdx = 0; // the start index of what hasn't been copied yet
var replacementCount = 0;
while( (idx = content.IndexOf( searchText, idx+1 )) != -1 ) {
    // copy everything leading up to our search text
    sb.Append( content.Substring( uncopiedIdx, idx-uncopiedIdx ) );
    // copy the replacement text, with the replacement count
    var replacement = "(" + replacementCount++ + ")";
    sb.Append( replacement );
    // skip over the search text
    uncopiedIdx = idx + searchText.Length;
}
// copy everything after the last match
sb.Append( content.Substring( uncopiedIdx ) );

您可以使用MatchEvaluator,它可以一次完成所有操作。
类似这样的事情-

C#

字符串内容=
@"
";
字符串fileName=“FILE”;
正则表达式jsRx=新正则表达式(
@"
“']|”“[^”“]*”“[^']*”)*?(?\s*([''”“])\s*x-fn\s*\1)#(1)引用
|(?>(?!\s*['”“])\s*x-fn(?=\s |>)
)
)
(?= 
(((?:[^>“”]]|“[^”“]*”[^']*)*?)(?\s*([^'])\s*javascript:void\(0\);\s*\3)#(3)引用
|(?>(?!\s*['”“])\s*javascript:void\(0\);(?=\s |>)
)
((?>(?:“”?“|”.*?”|[^>]?)+)#(4)-“href”之后
)
(?>\s+(?:“”?“|”.*?“|[^>]*?)+
>        
) (? )
“,RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
int计数器=0;
字符串contentNew=jsRx.Replace(内容,委托(匹配)
{
返回“”;
});
Console.WriteLine(contentNew);
输出

<a class="x-fn" href="FILE#fn0">
<a class='x-fn' href="FILE#fn1">
<a href="FILE#fn2" class=x-fn >
<a class="x-fn" href="FILE#fn3" >
<a 'hello' href="FILE#fn4" world class=x-fn >

您可以使用MatchEvaluator,它可以一次完成所有操作。
类似这样的事情-

C#

字符串内容=
@"
";
字符串fileName=“FILE”;
正则表达式jsRx=新正则表达式(
@"
“']|”“[^”“]*”“[^']*”)*?(?\s*([''”“])\s*x-fn\s*\1)#(1)引用
|(?>(?!\s*['”“])\s*x-fn(?=\s |>)
)
)
(?= 
(((?:[^>“”]]|“[^”“]*”[^']*)*?)(?\s*([^'])\s*javascript:void\(0\);\s*\3)#(3)引用
|(?>(?!\s*['”“])\s*javascript:void\(0\);(?=\s |>)
)
((?>(?:“”?“|”.*?”|[^>]?)+)#(4)-“href”之后
)
(?>\s+(?:“”?“|”.*?“|[^>]*?)+
>        
) (? )
“,RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
int计数器=0;
字符串contentNew=jsRx.Replace(内容,委托(匹配)
{
返回“”;
});
Console.WriteLine(contentNew);
输出

<a class="x-fn" href="FILE#fn0">
<a class='x-fn' href="FILE#fn1">
<a href="FILE#fn2" class=x-fn >
<a class="x-fn" href="FILE#fn3" >
<a 'hello' href="FILE#fn4" world class=x-fn >


你知道你也可以使用HtmlAgilityPack进行HTML编辑,对吗?为什么要使用正则表达式?简单的字符串替换就可以了..特别是因为你的搜索字符串不是正则表达式!!!使用调试器。也许你的正则表达式找不到匹配项。我还建议使用字符串替换,就像banging说的那样。不用担心特殊的正则表达式符号是这样的。你知道你也可以使用HtmlAgilityPack进行HTML编辑,对吗?为什么要使用正则表达式?一个简单的字符串替换就可以了..特别是因为你的搜索字符串不是正则表达式!!!使用debu