Java регулярное выражение и "жадный" или ранний поиск слэша - PullRequest
1 голос
/ 31 января 2020
Text:
123/444_ab/alphanum/alphanum/alphanum.sss
256/333_123/alphanum/alphanum.fff
777/999_abcde/alphanum.ggg

Я хочу две группы.

  1. совпадения первой группы: 123,256 и 77
  2. совпадения второй группы: 444_ab, 333_123 и 999_abcde.

Проблема в том, что любое регулярное выражение, которое я придумал, включает в себя дополнительные косые черты для второй группы. eg333_123 / alphanum

ex. 
(\\d{3})/\\d{3}_.+)/.+[.].+

Нужно просто дать первые две группы со следующим sla sh.

Ответы [ 4 ]

4 голосов
/ 31 января 2020

Кроме того, подобное требование также может быть легко обработано любой функцией «разбить на строку». Разделив на '/', чтобы получить массив значений и go оттуда ...

Я обнаружил, что это часто намного легче читать и отлаживать, чем "куриные царапины регулярного выражения" когда данные имеют такой формат, как вы показываете здесь. Он также «очевидно» покажет, что должно произойти, когда данные содержат 5, 4 или 3 группы, как вы продемонстрировали в своем посте, и будет работать для любого числа групп.

1 голос
/ 31 января 2020
^(.*?)\/(.*?)\/.*

Это регулярное выражение должно помочь.

0 голосов
/ 31 января 2020

Используйте *? для не жадного совпадения: ^(.*?)/(.*?)/.*.

.*? будет соответствовать только тому количеству символов, которое необходимо для совпадения всего выражения.

import java.util.regex.*;

public class MyClass {
    public static void main(String args[]) {
        String a = "123/444_ab/alphanum/alphanum/alphanum.sss";
        String b = "256/333_123/alphanum/alphanum.fff";
        String c = "777/999_abcde/alphanum.ggg";
        Pattern p = Pattern.compile("^(.*?)/(.*?)/.*");

        Matcher m = p.matcher(a);
        if (m.matches()) {
            System.out.println("a:");
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        } else {
            System.out.println("'a' doesn't match.");
        }

        m = p.matcher(b);
        if (m.matches()) {
            System.out.println("b:");
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        } else {
            System.out.println("'b' doesn't match.");
        }

        m = p.matcher(c);
        if (m.matches()) {
            System.out.println("c:");
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        } else {
            System.out.println("'c' doesn't match.");
        }
    }
}

Вывод:

a:
123
444_ab
b:
256
333_123
c:
777
999_abcde
0 голосов
/ 31 января 2020

Преобразование моего комментария в ответ, чтобы решение было легко найти для будущих посетителей.

Вы можете использовать это регулярное выражение в режиме MULTILINE:

(?m)^(\\d{3})/(\\d{3}_[^/]+)

RegEx Demo

Подробности RegEx:

  • (?m): включить встроенный режим MULTILINE, чтобы ^ соответствовал началу каждой строки
  • ^: начало строки
  • (\\d{3}): первая группа захвата, соответствующая 3 цифрам
  • /: соответствие /
  • (\\d{3}_[^/]+): Вторая группа захвата соответствует 3 цифрам, затем _, затем 1 или более любому символу, который не является /
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...