使用正则表达式替换删除行

4

我试图从文件中删除以相同单词开头的行。我非常确定正则表达式是正确的,但它似乎不起作用。我认为可能不是这样工作,所以我尝试用一个非空字符串替换。然而它仍然不起作用。有什么建议如何修复这个问题或者其他方法实现相同的功能?

string pattern = @"^smth";
 Regex rgx = new Regex(pattern);
 File.WriteAllText(path, rgx.Replace(File.ReadAllText(path), ""));

那就一定是你的正则表达式有问题了。 你试过这里的例子了吗: https://msdn.microsoft.com/zh-cn/library/xwewhkd1(v=vs.110).aspx - LzyPanda
1个回答

4

您不需要使用正则表达式,我认为您只需要逐行读取文件,并检查每一行是否以smth开头。要在同一位置写入,请创建文件的临时副本,然后再将其删除。

var tmpfile = Path.GetTempPath() + ".mytmpfile.txt";
File.Copy(path, tmpfile, true);
using (var sw = new StreamWriter(path, false, Encoding.UTF8))
{
    using (var sr = new StreamReader(tmpfile, true))
    {
         var line = string.Empty;
         while ((line = sr.ReadLine()) != null)
         {
             if (!line.Trim().StartsWith("smth"))
                sw.WriteLine(line);
         }
    }
    File.Delete(tmpfile);
}

您的正则表达式不错,但如果您需要将整个文件读入变量,然后使用正则表达式处理多行文本,则需要使用multiline模式:string pattern = @"(?m)^smth";(?m)将强制^匹配的开头,而不是整个字符串的结尾。或者在Regex.Replace中使用RegexOptions.Multiline标志。

更新:

您的方法是有效的,但正则表达式应该像这样:(?m)^\s*smth\b.*(?:\r?\n|\z)

string pattern = @"(?m)^\s*smth\b.*(?:\r?\n|\z)";
Regex rgx = new Regex(pattern);
File.WriteAllText(path, rgx.Replace(File.ReadAllText(path), ""));

然而,如果你有大文件,我更愿意采用非正则表达式解决方案。

1
我为什么需要临时文件?我不能直接在原始文件中进行更改吗?另外,WriteLine 是什么意思?我想删除以某个单词开头的整行,而不是写入它。 - Dave Demirkhanyan
1
@DDavid:你可以通过将文件内容读入变量中,然后确保文件被释放后再写入来摆脱临时文件。我只是不知道你的文件有多大。我通常需要处理大于1GB的文件:( - Wiktor Stribiżew
1
你可以使用.Trim()去除空格,并检查修剪后的字符串是否以smth开头。 - Wiktor Stribiżew
1
刚刚检查了一下,看起来你的方法也很有效。我只需要稍微修改一下正则表达式,使其匹配以可选空格(\s*)开头的整行,然后是你想要搜索的单词,接着是任意字符直到换行符或字符串结尾(.*(?:\r?\n|\z))。 - Wiktor Stribiżew
1
你只需要告诉正则表达式引擎,你需要一个完整的单词 smth,只需在 smth 后面添加 \b 即可。然后,以 smths 开头的行将保持不变。 - Wiktor Stribiżew
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接