Java regex: повторение групп захвата - PullRequest
23 голосов
/ 04 августа 2011

Элемент - это разделенный запятыми список из одной или нескольких строк из цифр или символов, например,

"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 ]

36 голосов
/ 04 августа 2011

Это верно. Вы не можете иметь «переменное» число групп захвата в регулярном выражении Java. Ваш шаблон имеет две группы:

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

Каждая группа будет содержать содержимое последнего совпадения для этой группы. Т.е., abc,12 будет переопределено на 30,asdf,2.

Похожие вопросы:

Решение состоит в том, чтобы использовать одно выражение (что-то вроде \((.+?)\)) и использовать matcher.find для перебора совпадений.

2 голосов
/ 04 августа 2011

Вы можете использовать регулярное выражение типа ([^,]+) в цикле или просто str.split(","), чтобы получить все элементы одновременно. Эта версия: str.split("\\s*,\\s*") даже допускает пробелы.

1 голос
/ 01 февраля 2017

(^ | \ s +) (\ S *) (($ | \ s +) \ 2) + с опцией игнорирования регистра / i

Она ушла из левого левого движения

пример здесь - 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   ` `
0 голосов
/ 14 июля 2014

Это может быть решением:

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

}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...