如何将正则表达式应用于字符串列表?
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);
我想知道是否有办法避免以下代码中的 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);