【发布时间】:2014-04-28 19:32:13
【问题描述】:
我必须处理一个大文件(几 MB)并从中删除以时间标记的 cmets。一个例子:
blablabla 12:10:40 I want to remove this
blablabla some more
even more bla
过滤后,我希望它看起来像这样:
blablabla
blablabla some more
even more bla
最好的方法应该是简化正则表达式:
Dataout = Regex.Replace(Datain, "[012][0123456789]:[012345][0123456789]:[012345][0123456789].*", string.Empty, RegexOptions.Compiled);
现在这非常适合我的目的,但它有点慢。我假设这是因为前两个字符 [012] 和 [0123456789] 与很多数据匹配(它是一个包含十六进制的 ASCII 文件数据,例如“0045ab0123”等)。所以正则表达式经常匹配前两个字符。
当我将正则表达式更改为
Dataout = Regex.Replace(Datain, ":[012345][0123456789]:[012345][0123456789].*", string.Empty, RegexOptions.Compiled);
它得到了巨大的加速,可能是因为文件中根本没有很多 ':'。好的!但是我仍然需要检查第一个“:”之前的两个字符是数字,然后删除该行的其余部分。
所以我的问题归结为:
- 如何让正则表达式首先搜索最不频繁出现的 ':' 并且只有在找到匹配项后才检查之前的两个字符?
或者也许还有更好的方法?
【问题讨论】:
-
日期前是否总是有空格?
-
lookbehind 在这里有用吗?我不确定lookbehind 是在找到潜在匹配之后还是在它检查匹配之前得到评估。
-
不,不幸的是前面并不总是有空格,所以它可能看起来像:“0A0B1216:43:11 blabla”。我同意如果有空间,搜索会更容易..
-
您真的应该阅读此stackoverflow.com/questions/513412/… 以更好地了解
RegexOptions.Compiled在哪些方面有助于您提高速度,以及在哪些方面对其不利,因此您可以正确利用它。 -
您可以使用
:(?<=[0-2][0-9]:)[0-5][0-9]:[0-5][0-9].*执行全局搜索,然后在matchCollection 中使用反向循环,使用match.index 和匹配长度删除子字符串。 AdrianHHH 用这种方式写了一个答案。
标签: c# regex performance match