如何将正则表达式应用于字符串列表
本文关键字:字符串 列表 应用于 正则表达式 | 更新日期: 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)
为最佳情况。