我要做的是打开一个文件并搜索“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();
然而,在写完和关闭之后......我打开文件并且没有进行任何更改。除此之外,我想要做的是为每个替换实例添加一个在“#fn”之后计数的数字。所以,基本上,每次我用另一个替换javascript链接时,我希望它是:
<a class="x-fn" href="fileName#fn1">
然后当我替换第二个javascript实例时,它会读取
<a class="x-fn" href="fileName#fn2">
依旧......
我想我必须计算javascript出现次数的实例,替换它,并使用for循环遍历所有新链接并在末尾添加#fn(n)?
答案 0 :(得分:2)
你的问题是你有元字符(在这种情况下,打开和关闭paren in“void(0)”)。而不是表示文字的开放和关闭的parens,而是创建一个正则表达式组,这会导致您的匹配失败。如果你用反斜杠逃避parens,它将按预期工作。
但是,由于您只是匹配字符串文字,因此根本不需要使用正则表达式;使用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 ) );
答案 1 :(得分:1)
您可以使用MatchEvaluator,它应该一次完成所有操作 像这样的东西 -
C#
string content =
@"
<a class=""x-fn"" href=""javascript:void(0);"">
<a class='x-fn' href = ""javascript:void(0); "">
<a href='javascript:void(0);' class=x-fn >
<a class=""x-fn"" href=javascript:void(0); >
<a 'hello' href=javascript:void(0); world class=x-fn >
";
string fileName = "FILE";
Regex jsRx = new Regex(
@"
<a
(?=\s)
(?=
(?: [^>""']|""[^""]*""|'[^']*')*? (?<=\s)
class \s*=
(?:
(?> \s* (['""]) \s* x-fn \s* \1 ) # (1) quote
| (?> (?!\s*['""]) \s* x-fn (?=\s|>) )
)
)
(?=
( (?: [^>""']|""[^""]*""|'[^']*')*? ) (?<=\s) # (2) - before 'href'
href \s*=
(?:
(?> \s* (['""]) \s* javascript:void\(0\); \s* \3 ) # (3) quote
| (?> (?!\s*['""]) \s* javascript:void\(0\); (?=\s|>) )
)
( (?> (?:"".*?""|'.*?'|[^>]?)+ ) ) # (4) - after 'href'
)
(?> \s+ (?:"".*?""|'.*?'|[^>]*?)+
>
) (?<! /> )
", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
int counter = 0;
string contentNew = jsRx.Replace( content, delegate(Match match)
{
return "<a" + match.Groups[2] + "href=\"" + fileName + "#fn" + (counter++) + "\"" + match.Groups[4] + ">";
});
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 >