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

本文关键字:字符串 列表 应用于 正则表达式 | 更新日期: 2023-09-27 18:05:18

我想知道是否有一种方法可以避免以下代码中的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$1");

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

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

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

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

然后,如果你想在输入中得到"lines",分割输出,就像在。net中最简单的方式在换行符上分割字符串一样?:

string[] outputLines = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

你不能用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$1");

或者一行字:

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

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

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

for (var i=0; i<lines1.Count; i++)
{
    lines1[i] = Regex.Replace(lines1[i],"bim(.*)","bom$1");
}
但是请注意,仍然为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$1");

这个扩展将允许你应用一个正则表达式到集合中的每个字符串,因为它使用延迟执行,它实际上不会做任何事情,直到你迭代它。因此,例如,如果您只需要检查第一行(可能是为了决定是否应该处理文件的其余部分),那么您就可以在不查看其余行的情况下快速退出。在这种情况下,我们可以为O(1)为最佳情况。