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

Java正则表达式:重复捕获组,java,regex,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 我想出了以下(不正确的)模式 对于最后一个示例,它仅与以下内容

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

"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
我想出了以下(不正确的)模式

对于最后一个示例,它仅与以下内容匹配

qqq,pp
abc,12
30,asdf,2
qqq,pp
30,asdf,2

小费?谢谢

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

\((.+?)\)(?:,\((.+?)\))*
  |___|        |___|
 group 1      group 2
每组将包含该组上次匹配的内容。也就是说,
abc,12
将被
30,asdf,2
覆盖

相关问题:


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

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

这可能是解决方案:

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\">"));

}
package com.drl.fw.sch;
导入java.util.regex.Pattern;
公共类AngularJSMatcher扩展了SimpleStringMatcher{
Matcher代表;
公共AngularJSMatcher(字符串查找){
超级(寻找);
//ng重复
int ind=lookFor.indexOf('-');
如果(ind>=0){
StringBuilder sb=新的StringBuilder();
布尔值优先=真;
for(字符串s:lookFor.split(“-”){
如果(第一){
某人追加;
第一个=假;
}否则{
如果(s.长度()>1){
sb.append(s.substring(0,1).toUpperCase());
sb.追加(s.子串(1));
}否则{
某人追加(s.toUpperCase());
}
}
}
委托=新的SimpleStringMatcher(sb.toString());
}否则{
字符串字[]=lookFor.split(“(?”);
System.out.println(matcher.match(“var ngRepeatStart=\”项目中的项目\“>”);
}
}(^ |\s+)(\s*)($|\s+)\2)+带忽略大小写选项/i

她现在走了

例如:


你能在“,”上拆分字符串并去掉剩下的括号来获得你的结果吗?当然想要。啊,好的,谢谢,我不知道,现在我要找出另一个选项是的。这确实很烦人。net有这个功能(如我链接的问题/答案所示)@大卫,万一你错过了,他已经给了你一个很好的选择:)