Java正则表达式:重复捕获组

时间:2011-08-04 10:06:02

标签: java regex

项目是逗号分隔的一个或多个数字或字符串的列表,例如

"12"
"abc"
"12,abc,3"

我正在尝试匹配Java中零个或多个项目的括号列表,例如

""
"(12)"
"(abc,12)"
"(abc,12),(30,asdf)"
"(qqq,pp),(abc,12),(30,asdf,2),"

应分别为最后一个示例返回以下匹配组

qqq,pp
abc,12
30,asdf,2

我想出了以下(不正确的)模式

\((.+?)\)(?:,\((.+?)\))*

仅匹配上一个示例的以下内容

qqq,pp
30,asdf,2

提示?感谢

4 个答案:

答案 0 :(得分:36)

没错。您不能在Java正则表达式中拥有“可变”数量的捕获组。您的模式有两组:

\((.+?)\)(?:,\((.+?)\))*
  |___|        |___|
 group 1      group 2

每个群组都会包含该群组最后一场比赛的内容。即,abc,12将被30,asdf,2覆盖。

相关问题:

解决方案是使用一个表达式(类似\((.+?)\))并使用matcher.find迭代匹配。

答案 1 :(得分:2)

您可以在循环中使用([^,]+)之类的正则表达式,或只使用str.split(",")来获取所有元素。此版本:str.split("\\s*,\\s*")甚至允许空格。

答案 2 :(得分:1)

(^ | \ s +)(\ S *)(($ | \ s +)\ 2)+ with ignore case option / i

她现在离开LEFT了

此处的示例 - https://regex101.com/r/FEmXui/2

Match 1
Full match  3-23    ` left LEft leFT LEFT`
Group 1.    3-4 ` `
Group 2.    4-8 `left`
Group 3.    18-23   ` LEFT`
Group 4.    18-19   ` `

答案 3 :(得分:0)

这可能是解决方案:

package com.drl.fw.sch;

import java.util.regex.Pattern;

public class AngularJSMatcher extends SimpleStringMatcher  {

Matcher delegate;


public AngularJSMatcher(String lookFor){
    super(lookFor);
    // ng-repeat 
    int ind = lookFor.indexOf('-');
    if(ind >= 0 ){
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String s : lookFor.split("-")){
            if(first){
                sb.append(s);
                first = false;
            }else{
                if(s.length() >1){
                    sb.append(s.substring(0,1).toUpperCase());
                    sb.append(s.substring(1));

                }else{
                    sb.append(s.toUpperCase());
                }
            }
        }
        delegate = new SimpleStringMatcher(sb.toString());
    }else {
        String words[] = lookFor.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
        if(words.length > 1 ){
            StringBuilder sb = new StringBuilder();
            for (int i=0;i < words.length;i++) {
                sb.append(words[i].toLowerCase());
                if(i < words.length-1) sb.append("-");
            }
            delegate = new SimpleStringMatcher(sb.toString());
        }

    }

}

@Override
public boolean match(String in) {
    if(super.match(in)) return true;
    if(delegate != null && delegate.match(in)) return true;

    return false;
}

public static void main(String[] args){
    String lookfor="ngRepeatStart";

    Matcher matcher = new AngularJSMatcher(lookfor);

    System.out.println(matcher.match( "<header ng-repeat-start=\"item in items\">"));
    System.out.println(matcher.match( "var ngRepeatStart=\"item in items\">"));

}

}