在 Java 正则表达式中包含注释

Posted

技术标签:

【中文标题】在 Java 正则表达式中包含注释【英文标题】:Including comments in Java regular expressions 【发布时间】:2010-11-25 14:30:06 【问题描述】:

我有一些复杂的正则表达式,我需要对其进行注释以提高可读性和维护性。 Java 规范相当简洁,我为此努力了很长时间。我终于发现了我的错误并将其作为答案发布,但我将不胜感激有关维护正则表达式的任何其他建议

作为一个例子,我想在一个简单的名称解析器中注释子组件(模式S):

    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 有一个很好的建议,可以避免嵌入 cmets。由于 java 和其他人已经为嵌入式 cmets 提供了它们在哪些情况下有用? (我想我有一个案例,但我很想看看其他人)。

编辑:如下所述@mikej,正则表达式不支持可选的初始良好,最好是:

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

但这最终会在初始时提取空间

【问题讨论】:

【参考方案1】:

我发现以下方法有效:

        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

【讨论】:

这是如何工作的?我刚刚测试了它,它不起作用。 哦,Pattern.COMMENTS 是关键。【参考方案2】:

你为什么不这样做:

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

继续:

如果您想保留 cmets 的模式并且需要从属性文件中读取它,请使用以下命令:

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

【讨论】:

好建议。这适用于许多简单的情况,但我希望正则表达式独立于使用它们的代码(例如,在外部数据文件中)。内联 cmets 仍然可见。【参考方案3】:

请参阅Martin FowlerComposedRegex 上的帖子,了解有关提高正则表达式可读性的更多想法。总之,他主张将复杂的正则表达式分解成更小的部分,这些部分可以被赋予有意义的变量名。例如

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

【讨论】:

谢谢 - 这是一个有用的方法。它还指出了使用域特定语言生成正则表达式的另一个想法 (flimflan.com/blog/ReadableRegularExpressions.aspx)。 (这实际上是我在我的应用程序中所做的,它具有复杂的科学数据正则表达式组合,但这超出了这个问题的范围)。 这是一个非常干净整洁的解决方案。虽然 optionalWhiteSpace 应该可能是强制的WhiteSpace? :) 感谢 crunchdog。我认为让我感到惊讶的是,OP 中的模式实际上存在一个限制,如果我们有一个没有中间首字母的名字,比如 Fred Bloggs,那么我们需要在名字和姓氏之间留 2 个空格来匹配这两个 \ \s+ 在模式中。我试图解决这个问题,但现在我已经编辑了答案以使模式等同于 OP 中的模式。 @mikej 谢谢 - 我已经添加了一个请求,可以为任何可以使它更漂亮的人编辑原件

以上是关于在 Java 正则表达式中包含注释的主要内容,如果未能解决你的问题,请参考以下文章

如何在正则表达式中包含变量[重复]

在这个正则表达式中包含“减号”,如何?

MySQL正则表达式匹配

在正则表达式字符括号中包含连字符?

如何使用正则表达式匹配 Ruby 中包含特殊字符的重复模式?

正则表达式匹配文本中包含换行符等空白字符如何匹配