Двойное разбиение регулярного выражения

Как должно выглядеть выражение регулярного выражения Java, если я хочу найти два совпадения

1. NEW D City 
2. 1259669

Из

Object No: NEW D City | Item ID: 1259669

Я пробовал с

(?<=:\s)\w+

но это только получить

 1. NEW
 2. 1259669

https://regex101.com/r/j5jwK2/1

Как выглядят ваши фактические входные данные? Состоит ли он из линий с парами, как вы показываете?

Sven Krüger 11.04.2018 13:09
(?<=:\s)\w+(\s+\w+)*? Но, возможно, лучше будет подходящий «синтаксический анализатор», который разбивает на |, а затем отображает карты с : (и обрезки).
Biffen 11.04.2018 13:10

Попробуйте s.split("\\s*\\|?\\s*[^:|]+:\\s*"), но более подходящий подход - сопоставить с :\s*([^:|]+) и обрезать .group(1).

Wiktor Stribiżew 11.04.2018 13:11

Вы можете использовать: (?<=:\s)[^|]+(?=\s|\z)

anubhava 11.04.2018 13:13

Я не уверен, что регулярное выражение - правильный инструмент для этого.

jsageryd 11.04.2018 13:13

@jsageryd вам все равно понадобится регулярное выражение для split("\\|").

Wiktor Stribiżew 11.04.2018 13:16
1
6
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать комбинацию двух разделений:

String key = "Object No: NEW D City | Item ID: 1259669";
String[] parts = key.split("\\s*\\|\\s*");
List<String> result = new ArrayList<>();
for (String part : parts) {
    String[] kvp = part.split(":\\s*");
    if (kvp.length == 2) {
        result.add(kvp[1]);
        System.out.println(kvp[1]); // demo
    }
}

См. Демонстрация Java

Сначала вы разделяете \\s*\\|\\s* (|, заключенный в 0+ пробелов), а затем :\\s*, двоеточие, за которым следует 0+ пробелов.

Другой подход - использовать :\s*([^|]+) шаблон и захватить и обрезать значение группы 1:

String s = "Object No: NEW D City | Item ID: 1259669";
List<String> result = new ArrayList<>();
Pattern p = Pattern.compile(":\\s*([^|]+)");
Matcher m = p.matcher(s);
while(m.find()) {
    result.add(m.group(1).trim());
    System.out.println(m.group(1).trim()); // For demo
}

Смотрите Демонстрация Java. В этом регулярном выражении ([^|]+) - это группа захвата (помещающая свое содержимое в matcher.group(1)), которая соответствует одному или нескольким (+) символам, отличным от | (с классом инвертированных символов [^|]).

Ответ принят как подходящий

Использовать шаблон для захвата обоих значений проще. Вот используемый регулярное выражение:

Object No:([^|]*)\| Item ID: (\d*)

И код, сгенерированный regex101 и адаптированный для соответствия желаемому результату.

    final String regex = "Object No: ([^|]*)\\| Item ID: (\\d*)";
    final String string = "Object No: NEW D City | Item ID: 1259669";

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

    while (matcher.find()) {
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println(+ i + ": " + matcher.group(i));
        }
    }

Выход:

1: NEW D City 
2: 1259669

Аналогичным, но более общим решением будет [^:]*[:\s]*([^|]*)\|[^:]*[:\s]*(\d*) (не идеально, я не пытался сделать что-то эффективное)

Другие вопросы по теме