java - 这个正则表达式可以进一步优化吗?

标签 java regex optimization scala

我写了这个正则表达式来解析 srt 文件中的条目。

(?s)^\d++\s{1,2}(.{12}) --> (.{12})\s{1,2}(.+)\r?$

我不知道这是否重要,但这是使用 Scala 编程语言(Java 引擎,但是是文字字符串,这样我就不必加倍反斜杠)完成的。

使用 s{1,2} 是因为有些文件只有换行符 \n 而其他文件会有换行符和回车符 \n\r 第一个 (?s) 启用 DOTALL 模式,以便第三个捕获组也可以匹配换行符。

我的程序基本上使用 \n\r?\n 作为分隔符来破坏 srt 文件,并使用 Scala 良好的模式匹配功能来读取每个条目以进行进一步处理:

val EntryRegex = """(?s)^\d++\s{1,2}(.{12}) --> (.{12})\s{1,2}(.+)\r?$""".r

def apply(string: String): Entry = string match {
  case EntryRegex(start, end, text) => Entry(0, timeFormat.parse(start),
    timeFormat.parse(end), text);
}

示例条目:

一行:

1073
01:46:43,024 --> 01:46:45,015
I am your father.

两行:

160
00:20:16,400 --> 00:20:19,312
<i>Help me, Obi-Wan Kenobi.
You're my only hope.</i>

问题是,探查器告诉我,这种解析方法是迄今为止我的应用程序中最耗时的操作(它进行密集的时间计算,甚至可以比读取和解析文件快几倍的速度重新编码文件项)。

那么任何正则表达式向导都可以帮助我优化它吗?或者,也许我应该牺牲正则表达式/模式匹配的简洁性并尝试使用老派的 java.util.Scanner 方法?

干杯,

最佳答案

(?s)^\d++\s{1,2}(.{12}) --> (.{12})\s{1,2}(.+)\r?$

在 Java 中,$ 表示输入的结束或紧接在输入结束之前的换行符的开始。 \z 意味着输入的明确结束,所以如果这也是 Scala 中的语义,那么 \r?$ 是多余的并且 $ 可以同样。如果你真的只想要最后一个 CR 而不是 CRLF,那么 \r?\z 可能会更好。

(?s) 还应该使 (.+)\r? 变得多余,因为 + 是贪婪的, . 应始终展开以包含 \r。如果您不希望 \r 包含在第三个捕获组中,则使匹配变得惰性:(.+?) 而不是 (.+).

也许

(?s)^\d++\s\s?(.{12}) --> (.{12})\s\s?(.+?)\r?\z

将在 JVM 中运行的正则表达式的其他高性能替代方案 &| CLR 包括 JavaCCANTLR .对于仅 Scala 的解决方案,请参阅 http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html

关于java - 这个正则表达式可以进一步优化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7115389/

相关文章:

mysql - 如何以最少的停机时间运行 OPTIMIZE TABLE

css - 优化 gulp Sass 编译

sql - 对一组数据使用整数而不是 varchar *真的*值得吗?

java - 我可以在模块 B 上重写模块 A 的方法吗?

javascript - RegEx 从 _GET 请求中获取值

java - 在大数据集上使用正则表达式时的空间和时间问题

正则表达式在 Notepad++ 中反向搜索

java - 结果集更新行不起作用

java - 启动NameNode失败

java - Android 聊天在 DataSnapshot.getValue() 上崩溃