2009-09-04 69 views
14

我有一些复杂的正则表达式,我需要为可读性和维护发表评论。 Java规范相当简洁,我努力了很长时间才得到这个工作。我终于抓住了我的错误,将发布它作为一个答案,但我会为任何其他建议感谢上保持正则表达式在Java正则表达式中包含注释

,因为我想在一个简单的名字解析器评论的子(模式)的例子:

String testTarget = "Waldorf T. Flywheel"; 
    String patternS = "([A-Za-z]+)\\s+([A-Z]\\.)?\\s+([A-Za-z]+)"; 
    Pattern pattern = Pattern.compile(patternS, Pattern.COMMENTS); 
    Assert.assertTrue(pattern.matcher(testTarget).matches()); 

编辑:我将不胜感激(?x)格式的例子。

编辑:@ geowa4有一个很好的建议,它可以避免嵌入评论。 Sinnce java和其他人提供了嵌入式评论他们有用的情况是什么? (我认为我有案子,但我有兴趣去看看其他人)。

编辑:如下@mikej正则表达式不支持可选的初始很好,会注意到更好,因为:

 String patternS = "([A-Za-z]+)\\s+([A-Z]\\.\\s+)?([A-Za-z]+)"; 

但最终会在最初

回答

21

查看ComposedRegexMartin Fowler后用于改善正则表达式的可读性一些更多的想法。总之,他主张将一个复杂的正则表达式分解成可以赋予有意义变量名称的较小部分。例如

String mandatoryName = "([A-Za-z]+)"; 
String mandatoryWhiteSpace = "\\s+"; 
String optionalInitial = "([A-Z]\\.)?"; 
String pattern = mandatoryName + mandatoryWhiteSpace + optionalInitial + 
    mandatoryWhiteSpace + mandatoryName; 
+0

谢谢 - 这是一个有用的方法。它还指出了使用域特定语言生成正则表达式的另一个想法(http://flimflan.com/blog/ReadableRegularExpressions.aspx)。 (这实际上是我在我的应用程序中做的,它对科学数据进行了复杂的正则表达式的复杂组合,但这超出了这个问题的范围)。 – 2009-09-04 11:56:25

+1

这是一个非常干净整洁的解决方案。尽管可选的白色空间应该可能是强制的白色空间? :) – crunchdog 2009-09-04 12:08:13

+0

感谢crunchdog。我认为是什么引起了我的注意,实际上OP中的模式存在一个限制,那就是如果我们有一个没有中间名的名字,比如Fred Bloggs,那么我们需要在名和姓之间使用两个空格,以便匹配两个\ \ s +模式中。我试图解决这个问题,但现在我编辑了答案,使模式等同于OP中的模式。 – mikej 2009-09-04 12:32:57

11

提取的空间,我找到了以下工作:

 String pattern2S = 
      "([A-Za-z]+)  # mandatory firstName\n" + 
      "\\s+    # mandatory whitespace\n " + 
      "([A-Z]\\.)?  # optional initial\n" + 
      "\\s+    # whitespace\n " + 
      "([A-Za-z]+)  # mandatory lastName\n"; 

关键的一点是要在字符串中包含换行字符\ n明确

15

你为什么不只是这样做:

String pattern2S = 
    "([A-Za-z]+)" + // mandatory firstName 
    "\\s+" +  // mandatory whitespace 
    ...; 

继续:

如果你想保持与该模式的意见,你需要从属性文件读取它,使用:

pattern=\ 
#comment1\\n\ 
(A-z)\ 
#comment2\\n\ 
(0-9) 
+0

好的建议。这可以在很多简单的情况下工作,但是我希望正则表达式独立于它们所使用的代码(例如在外部数据文件中)。内联注释仍然可见。 – 2009-09-04 11:26:57