Java Regex. группа без разделителей - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь разбить мою строку с помощью регулярных выражений. Он должен включать даже совпадения нулевой длины до и после каждого разделителя. Например, если разделитель равен ^, а моя строка равна ^^^, я ожидаю получить 4 группы нулевой длины. Я не могу использовать только regex = "([^\\^]*)", потому что он будет включать дополнительные совпадения нулевой длины после каждого true совпадения между разделителями. Поэтому я решил использовать символы без разделителя, следующие после начала строки или после разделителя. Он отлично работает на https://regex101.com/ (извините, я не смог найти вариант обмена на этом веб-сайте, чтобы поделиться своим примером) , но в Intellij IDEa он пропускает одно совпадение.

Итак, теперь мой код:

final String regex = "(^|\\^)([^\\^]*)";
final String string = "^^^^";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

while (matcher.find()) 
    System.out.println("[" + matcher.start(2) + "-" + matcher.end(2) + "]: \"" + matcher.group(2) + "\"");

и я ожидаю 5 совпадений с пустой строкой. Но у меня только 4:

[0-0]: ""
[2-2]: ""
[3-3]: ""
[4-4]: ""

Вопрос в том, почему он пропускает [1-1] совпадение и как я могу это исправить?

1 Ответ

0 голосов
/ 06 сентября 2018

Ваше регулярное выражение соответствует либо началу строки, либо ^ (захватывая это в группу 1), а затем любым 0+ символам, отличным от ^, в группу 2. Когда найдено первое совпадение (начало строки ), первая группа содержит пустую строку (так как это начало строки), а группа 2 также содержит пустую строку (так как первый символ равен ^, а [^^]* может соответствовать пустой строке перед несоответствующим символом Все совпадение имеет нулевую длину, и механизм регулярных выражений перемещает индекс регулярного выражения в следующую позицию. Таким образом, после первого совпадения индекс регулярного выражения перемещается из начала строки в позицию после первого ^. Затем найдено второе совпадение, второе ^ и пустая строка после него, следовательно, первое ^ не сопоставлено, оно пропущено.

Решение простое split:

String[] result = string.split("\\^", -1);

Второй аргумент заставляет метод выводить все пустые совпадения в конце полученного массива.

См. Демонстрационную версию Java :

String str = "^^^^";
String[] result = str.split("\\^", -1);
System.out.println("Number of items: " + result.length);
for (String s: result) {
    System.out.println("\"" + s+ "\"");
}

Выход:

Number of items: 5
""
""
""
""
""
...