从StreamReader获取与C#中的正则表达式匹配的有效方法

时间:2015-12-27 10:42:33

标签: c# stream streamreader

我有一个文件,我想得到与正则表达式查询匹配的文件行。

我的代码是这样的:

Assembly assembly = typeof(EmbeddedResourceGetter).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream(resourcePath);
StreamReader sr = new StreamReader(stream);

return file.ReadToEnd()
    .Split('\n').ToList()
    .Find(l => Regex.IsMatch(l, "regex-query-here"));

然而,我觉得这样效率很低,如果我需要多次重复,可能需要很长时间才能完成。

那么是否有更有效的方法来获取与正则表达式查询匹配而不读取整个文件的行,或者我是否必须以不同的方式重构我的代码以使其更有效?

2 个答案:

答案 0 :(得分:2)

Find只获得第一场比赛。所以,如果你真的想要第一场比赛不要读整个文件。效率低下。使用File.ReadLines

逐行读取文件

在每次迭代中使用Regex.IsMatch都是低效的。只创建一次正则表达式。

Regex regex = new Regex("regex-query-here");
return File.ReadLines(path).FirstOrDefault(l => regex.IsMatch(l));

File.ReadLines一次只加载一行内存。只要找到第一个匹配项,FirstOrDefault就会停止迭代。因此,如果您的比赛是在第23行,您将只从文件中读取23行,您将得到结果。

将所有文件读入内存可能会更快,但这需要在内存和性能之间进行权衡。

我必须提到的另一件事是,按\n分割并不是一种跨平台的获取线路的方法。

答案 1 :(得分:1)

您应该读取文件一次,将其存储在变量中,因为I / O操作很昂贵。然后,在变量上运行正则表达式。

当您将文件读入变量时,您将其从硬盘读取到RAM,访问RAM速度很快,硬盘速度很慢。 毫无疑问最好是从硬盘读取一次!

如果要匹配多行模式,也会逐行读取。

例如:

Can
you
match
me
if
you
read
me
line
by
line?

“Can \ s + you”正则表达式在这种情况下无法匹配,因为你不会在同一个字符串中得到“Can”和“you”。