【问题标题】:How to optimize a regex pattern?如何优化正则表达式模式?
【发布时间】:2023-04-01 07:36:01
【问题描述】:

我正在尝试从文本中获取子字符串并使用正则表达式。 示例文本:

bla bla 1:30-2pm bla bla 5-6:30am 一些文字 1-2:15am

我正在寻找时间框架条目(1-30-2pm...)。将它们加粗只是为了便于阅读

这是我的正则表达式:

\d{1,2}(:\d{1,2})? – \d{1,2}(:\d{1,2})?(am|pm)

java sn-p:

public static List<String> foo(String text, String regex) {
    List<String> entries = new ArrayList<>();
    Matcher matcher = Pattern.compile(regex).matcher(text);
    while (matcher.find()) {
        entries.add(matcher.group());
    }
    return entries;
}

你能帮我优化正则表达式模式吗?可能有一些我错过的用例。

【问题讨论】:

    标签: java regex text regex-lookarounds regex-group


    【解决方案1】:

    如果我们想优化我们的表达式,我们可能想要添加可选空格,以防我们的输入可能有任何额外的空格,除此之外,您的表达式看起来很棒:

    (\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)
    

    如果我们希望获取数据,我们还添加了捕获组。

    Demo 1

    或者:

    (\d{1,2})(:\d{1,2})?(\s+)?(am|pm)?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)
    

    Demo 2

    随心所欲。

    测试

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    final String regex = "(\\d{1,2})(:\\d{1,2})?(\\s+)?-(\\s+)?(\\d{1,2})(:\\d{1,2})?(am|pm)";
    final String string = "bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am\n"
         + "bla bla 1:30 - 2pm bla bla 5  - 6:30am some text 1 - 2:15am";
    
    final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
    final Matcher matcher = pattern.matcher(string);
    
    while (matcher.find()) {
        System.out.println("Full match: " + matcher.group(0));
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println("Group " + i + ": " + matcher.group(i));
        }
    }
    

    正则表达式

    如果不需要此表达式并且您希望对其进行修改,请访问此链接regex101.com

    正则表达式电路

    jex.im 可视化正则表达式:

    【讨论】:

    • 感谢 jex.im
    【解决方案2】:

    我建议使用像这样的正则表达式

    String regex = "(?i)(?<!\\d)(?:0?[1-9]|1[0-2])(?::[0-5]\\d)?\\p{Pd}(?:0?[1-9]|1[0-2])(?::[0-5]\\d)?[ap]m\\b";
    

    regex demo

    详情

    • (?i) - 不区分大小写的标志(用于AMPMampm 值等)
    • (?&lt;!\d) - 左边不允许有数字
    • (?:0?[1-9]|1[0-2]) - 一个可选的0,然后是从19 的数字,或1,然后是012
    • (?::[0-5]\d)? - 可选组:从05 的数字,然后是任意一个数字
    • \p{Pd} - 任何连字符
    • (?:0?[1-9]|1[0-2])(?::[0-5]\d)? - 见上文
    • [ap]m\b - ap 然后是 m 和一个单词边界。

    【讨论】:

      猜你喜欢
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多