如何将正则表达式应用于字符串列表?

How to apply a regex to a string list?

我想知道是否有办法避免以下代码中的 foreach 循环:

List<string> lines1 = new List<string>();
List<string> lines2 = new List<string>();
lines1.AddRange(File.ReadAllLines("in.txt"));
foreach(string s in lines1)
    lines2.Add(Regex.Replace(s,"bim(.*)","bom");

请注意,循环在处理过程中还需要有两个列表。我的目标是将正则表达式应用到列表中的每个字符串 原位

只需使用常规 for 循环即可避免额外列表的需要

for (var i=0; i<lines1.Count; i++)
{
    lines1[i] = Regex.Replace(lines1[i],"bim(.*)","bom");
}

但是请注意,您 仍在为 lines1 中的每个字符串创建一个新字符串,因为字符串是不可变的。

或者,如果你愿意,你可以只写一个扩展方法,像这样应该可以工作:

public static class Extensions
{
    public static IEnumerable<string> RegexReplace (this IEnumerable<string> strings, Regex regex, string replacement)
    {
        foreach (var s in strings)
        {
            yield return regex.Replace(s, replacement);
        }
    }
}

你可以这样称呼它:

var lines1 = File.ReadLines("in.txt").RegexReplace("bim(.*)","bom");

此扩展允许您将正则表达式应用于集合中的每个字符串,并且由于它使用延迟执行,因此在您迭代它之前它实际上不会做任何事情。因此,举例来说,如果您只需要检查第一行(可能决定是否应处理文件的其余部分),您就可以在不查看其余行的情况下使用快捷方式。在这种情况下,最好的情况是 O(1)

你不能用 foreach 来做,因为你不能在遍历它的同时修改集合,但你可以使用 for:

List<string> lines = new List<string>(File.ReadAllLines("in.txt"));
for(int i = 0; i < lines.Count; i++)
    lines[i] = Regex.Replace(lines[i],"bim(.*)","bom");

或者单行:

List<string> lines = File.ReadLines("in.txt")
                         .Select(s => Regex.Replace(s ,"bim(.*)","bom"))
                         .ToList();

请注意 ReadLines 不会将整个文件读入内存,因此投影会在从文件中读取行时对其进行转换(这意味着不会创建第二个集合)。

不想迭代。然后不要创建一个集合,而是在一个字符串中读取整个文件:

string input = File.ReadAllText("in.txt");
string output = Regex.Replace(input, "bim(.*)", "bom");

然后如果你想在输入中得到 "lines",按照 Easiest way to split a string on newlines in .NET?:

中的解释拆分输出
string[] outputLines = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);