0

我正在尝试创建一个正则表达式来捕获两个捕获组之间的令牌。

示例输入

Added experiencevalidator [Java] [Spring]
1.  Added validators [Java] [Spring]
2.  Fixed issues with deletes [JPA] [Java]

基本上我想捕获编号(1.,2.)和标签([Java] [Spring])之间的标记。

预期捕获

匹配器应为每一行返回以下内容:

Added experiencevalidator
Added validators
Fixed issues with deletes

我目前正在使用这段代码,它利用了积极的前瞻和后瞻。

private Pattern TITLE_REGEX = Pattern.compile("(?<=\\d\\.\\s)(.*?)(?=\\[.*)");

private String cleanseTitle(String title){
    Matcher m = TITLE_REGEX.matcher(title);
    if(m.find()){
        System.out.println("Match found");
        System.out.println(m.group(1));;
    }else{
        System.out.println("No Match");
    }
    return title;
}

每行都cleanseTitle通过 title 参数传递给方法。我的问题是我不确定如何处理前面没有编号的行。该代码当前正确处理前面有编号的行,但是那些前面没有编号的行返回不匹配。

任何人都可以为我提供一个正则表达式来处理前面有编号的行或前面没有编号的行吗?我对任何正则表达式解决方案持开放态度,而且我不喜欢我当前的正则表达式,因此请随时更改它。任何可以帮助我了解更多有关正则表达式的随附解释也值得赞赏。

4

3 回答 3

1

您可以使用两个正则表达式:

  1. 无所取代^\d+\.\s+
  2. 无所取代(\s+\[[^]]+\])*\s*$

当然,不要忘记将 Java 字符串中的所有反斜杠加倍。

请注意,您不需要测试匹配:如果正则表达式不匹配,则不会发生替换。

示例代码:

private static final String
    BEGINNING_NUMBERS = "^\\d+\\.\\s+",
    ENDING_TOKENS = "(\\s+\\[[^]]+\\])*\\s*$";

private String cleanseTitle(String title)
{
    return title.replaceFirst(BEGINNING_NUMBERS, "")
        .replaceFirst(ENDING_TOKENS, "");
}
于 2012-12-29T22:20:50.797 回答
1

只修复你的正则表达式而不写一个新的,你在一开始就匹配一个数字。为什么不让它成为可选的。

(?<=\\d\\.\\s)?(.*?)(?=\\[.*)
于 2012-12-29T22:21:02.063 回答
1

由于您使用捕获组,因此您不需要环顾四周。我会将后视更改为交替,以匹配编号或前导可选空格:

^(?:\d+\.\s|\s*)(.*?)(?=\[.*)

在 Regexr 上查看

交替中的顺序在这里很重要。您需要将编号作为第一个替代,因为第二个替代将始终匹配。

你也可以用这个跳过前瞻和惰性量词

^(?:\d+\.\s|\s*)([^\[]+)

在 Regexr 上查看

于 2012-12-29T22:31:39.080 回答