Как написать группу захвата регулярного выражения, которая соответствует символу 3 или 4 раза перед разделителем? - PullRequest
3 голосов
/ 18 октября 2019

Я пытаюсь написать регулярное выражение, которое разделяет элементы в соответствии с разделителем. Регулярное выражение также должно гарантировать, что в идеале должно быть 4, но не менее 3 двоеточий : в каждом совпадении.

Вот пример строки:

"Checkers, etc:Blue::C, Backgammon, I say:Green::Pepsi:P, Chess, misc:White:Coke:Florida:A, :::U"

Отсюда должно быть 4совпадения:

  • Checkers, etc:Blue::C
  • Backgammon, I say:Green::Pepsi:P
  • Chess, misc:White:Coke:Florida:A
  • :::U

Вот что я попробовал до сих пор:

([^:]*:[^:]*){3,4}(?:, )

Regex 101 at: https://regex101.com/r/O8iacP/8

Я попытался создать группу без захвата для ,

Затем я попытался сопоставить группу любому символу, который не является :, :, и любому символу, который не : 3 или 4 раза.

Код, который я использую для итерацииэти группы:

String line = "Checkers, etc:Blue::C, Backgammon, I say::Pepsi:P, Chess:White:Coke:Florida:A, :::U";
String pattern = "([^:]*:[^:]*){3,4}(?:, )";

  // Create a Pattern object
  Pattern r = Pattern.compile(pattern);

  // Now create matcher object.
  Matcher matcher = r.matcher(line);
  while (matcher.find()) {
        System.out.println(matcher.group(1));
    }

Любая помощь приветствуется!

Редактировать

Используя регулярное выражение @ Casimir, все работает. Мне пришлось изменить приведенный выше код, чтобы использовать группу (0) следующим образом:

String line = "Checkers, etc:Blue::C, Backgammon, I say::Pepsi:P, Chess:White:Coke:Florida:A, :::U";
String pattern = "(?![\\s,])(?:[^:]*:){3}\\S*(?![^,])";

// Create a Pattern object
Pattern r = Pattern.compile(pattern);

// Now create matcher object.
Matcher matcher = r.matcher(line);
while (matcher.find()) {
    System.out.println(matcher.group(0));
}

Теперь печатает:

Checkers, etc:Blue::C
Backgammon, I say::Pepsi:P
Chess:White:Coke:Florida:A
:::U

Еще раз спасибо!

Ответы [ 3 ]

2 голосов
/ 18 октября 2019

Я предлагаю этот шаблон:

(?![\\s,])(?:[^:]*:){3}\\S*(?![^,])

Отрицательные предвкушения избегают совпадения с начальными или конечными разделителями. Второй, в частности, заставляет совпадение следовать за разделителем или концом строки (, за которым не следует символ, который не является запятой ).

demo

Обратите внимание, что шаблон не имеет групп захвата, поэтому результатом является полное совпадение (или группа 0).

1 голос
/ 18 октября 2019

Вы, кажется, делаете это сложнее, чем нужно с предвкушением (которое все равно не будет удовлетворено в конце строки).

([^:]*:){3}[^:,]*:?[^:,]*

Найдите первые 3 :'s, затем начните включать , в отрицательные группировки, с дополнительным 4-м :.

1 голос
/ 18 октября 2019

Вы можете использовать

(?:[^,:]+, )?[^:,]*(?::+[^:,]+)+
  • (?:[^,:]+, )? При желании сопоставить 1+ с любым символом, кроме , или :, за которым следует , и пробел
  • [^:,]* Соответствует 0+ любому символу, кроме : или ,
  • (?: Группа без захвата
    • :+[^:,]+ Соответствует 1+ : и 1+ раз любому символу, кроме : и ,
  • )+ Закрыть группу и повторить 1+ раз

Regex demo

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