Java Regex Matcher跳过比赛

时间:2018-05-10 14:43:06

标签: java regex string pattern-matching matcher

下面是我的Java代码,用于删除匹配的所有相邻字母对,但是我在Java Matcher类中遇到了一些问题。

  

我的方法

我试图在输入中找到所有连续重复的字符,例如

aaa, bb, ccc, ddd

接下来将奇数长度匹配替换为最后匹配的模式,甚至长度匹配"",即

aaa -> a
bb -> ""
ccc -> c
ddd -> d
s has single occurrence, so it's not matched by the regex pattern and excluded from the substitution

我正在调用Matcher.appendReplacement根据组长度(偶数或奇数)对输入中匹配的模式进行条件替换。

  

代码:

public static void main(String[] args) {
        String s = "aaabbcccddds";
        int i=0;
        StringBuffer output = new StringBuffer();
        Pattern repeatedChars = Pattern.compile("([a-z])\\1+");
        Matcher m = repeatedChars.matcher(s);
        while(m.find()) {
            if(m.group(i).length()%2==0)
                m.appendReplacement(output, "");
            else
                m.appendReplacement(output, "$1");
            i++;
        }
        m.appendTail(output);
        System.out.println(output);
    }

输入:aaabbcccddds

实际输出:aaabbcccds(仅ddd替换为d但跳过aaabbccc

预期输出:acds

2 个答案:

答案 0 :(得分:1)

您可以这样尝试:

public static void main(String[] args) {
    String s = "aaabbcccddds";
    StringBuffer output = new StringBuffer();
    Pattern repeatedChars = Pattern.compile("(\\w)(\\1+)");
    Matcher m = repeatedChars.matcher(s);
    while(m.find()) {
        if(m.group(2).length()%2!=0)
            m.appendReplacement(output, "");
        else
            m.appendReplacement(output, "$1");
    }
    m.appendTail(output);
    System.out.println(output);
}

它与你的相似,但是在获得第一个匹配第一个字符的组时,你的长度始终为0.这就是为什么我引入第二个匹配的相邻字符组的原因。因为它的长度为-1,所以我将奇数偶数逻辑反转为瞧 -

  

ACD的

已打印。

答案 1 :(得分:1)

您不需要多个if语句。尝试:

# Constraint for maximum upload file size (in KB)
backoffice.fileUpload.maxSize=10000

替换为(?:(\\w)(?:\\1\\1)+|(\\w)\\2+)(?!\\1|\\2)

Regex live demo

Java代码:

$1

Java live demo

正则表达式细分:

  • str.replaceAll("(?:(\\w)(?:\\1\\1)+|(\\w)\\2+)(?!\\1|\\2)", "$1"); 开始非捕获组
    • (?:捕获一个单词字符
    • (\\w)匹配偶数个相同的字符
    • (?:\\1\\1)+
    • |捕获一个单词字符
    • (\\w)匹配任意数量的相同字符
  • \\2+非捕获组结束
  • )之前没有捕获的字符

(?!\\1|\\2)PatternMatcher一起使用:

StringBuffer