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
Советы? Благодаря
Ответы
Ответ 1
Это правильно. Вы не можете иметь "переменное" количество групп захвата в регулярном выражении Java. Ваш шаблон имеет две группы:
\((.+?)\)(?:,\((.+?)\))*
|___| |___|
group 1 group 2
Каждая группа будет содержать содержимое последнего совпадения для этой группы. I.e., abc,12
будет переопределяться на 30,asdf,2
.
Похожие вопросы:
Решение состоит в том, чтобы использовать одно выражение (что-то вроде \((.+?)\)
) и использовать matcher.find
для итерации по совпадениям.
Ответ 2
Вы можете использовать регулярное выражение типа ([^,]+)
в цикле или просто str.split(",")
, чтобы сразу получить все элементы. Эта версия: str.split("\\s*,\\s*")
позволяет даже пробелы.
Ответ 3
(^ |\s +) (\ S *) (($ |\s +)\2) + с опцией случая игнорирования /i
Теперь она оставила left 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 ` `
Ответ 4
Это может быть решение:
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\">"));
}
}