我正在编写一个CSV解析器,为了检测我可以在文件上获得的不同数据类型,我为每种数据类型都有一个Map,每个数据类型包含我定义为有效且可识别的正则表达式。例如,对于我的Integer值,这是我的Map:
Map<String, String> integerFormatRegexps = new HashMap<String, String>();
integerFormatRegexps.put("^[1-9]\\d{1,9}$", "##0");
integerFormatRegexps.put("^-[1-9]\\d{1,9}$", "-##0");
integerFormatRegexps.put("^0$", "0");
现在,我在SO中看到了几个examples,而不是将这些正则表达式分开,它们使用的是Alternations,而不是三个正则表达式,我只能使用一个:
Map<String, String> integerFormatRegexps = new HashMap<String, String>();
integerFormatRegexps.put("^[1-9]\\d{1,9}$|^-[1-9]\\d{1,9}$|^0$", "Integer");
我的问题是,当在Java中匹配模式时,这两种方法中的哪一种通常会更有效?迭代通过单独的简单正则表达式找到匹配,或者只匹配一个更复杂的正则表达式?
答案 0 :(得分:1)
首先,我必须说效率不太可能成为你的问题。你的正则表达式相对简单,你似乎正在使用它们来提取它们之后的隔离值。
也就是说,需要注意的是,不同的分支可以匹配相同的字符。最好的例子是(.|\s)
,有时由尚未了解DOTALL / Singleline模式的正则表达式初学者使用(或[\S\s]
,如this question)。把它放在其他良性正则表达式的中间,用它来搜索一个不特别大的文本,然后看着你的计算机变成紧张性精神病。
您的示例正则表达式很好,因为每个分支都必须以不同的([1-9]
,-
或0
)开头。但正如我所说,我认为正则表达式的效率永远不会成为一个问题。做任何你认为更方便的事情;是否更紧凑的代码和更少的正则表达式是一个合理的权衡更大,更难维护的正则表达式?
还有一件事:如果你在紧密循环中反复使用正则表达式,请务必使用缓存的Pattern对象;编译它们的成本很高。实际上,考虑将它们存储在Map中作为Patterns而不是Strings。例如:
Pattern integerRegex = Pattern.compiile("^[1-9]\\d{1,9}$|^-[1-9]\\d{1,9}$|^0$");
Map<String, String> integerFormatRegexps = new HashMap<String, String>();
integerFormatRegexps.put(integerRegex, "Integer");
然后您可以使用静态Pattern.matches()
方法执行检查。