Нужна помощь в сопоставлении регулярных выражений - PullRequest
0 голосов
/ 23 октября 2018

Это может быть очень просто, но я чрезвычайно новичок в регулярных выражениях и у меня есть требование, когда мне нужно сделать несколько совпадений регулярных выражений в строке и извлечь число в ней.Ниже приведен мой код с образцом i / p и требуемым o / p.Я пытался создать Pattern, ссылаясь на https://www.freeformatter.com/java-regex-tester.html,, но само совпадение с регулярным выражением возвращает значение false.

Pattern pattern = Pattern.compile(".*/(a-b|c-d|e-f)/([0-9])+(#[0-9]?)");
String str = "foo/bar/Samsung-Galaxy/a-b/1"; // need to extract 1.
String str1 = "foo/bar/Samsung-Galaxy/c-d/1#P2";// need to extract 2.
String str2 = "foo.com/Samsung-Galaxy/9090/c-d/69"; // need to extract 69

System.out.println("result " + pattern.matcher(str).matches());
System.out.println("result " + pattern.matcher(str1).matches());
System.out.println("result " + pattern.matcher(str1).matches());

Все вышеприведенные СОПы возвращают значение false.Я использую Java 8, есть ли способ, с помощью которого в одном утверждении я могу сопоставить шаблон, а затем извлечь цифру из строки.

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

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Поскольку вы всегда соответствуете последнему числу в вашем регулярном выражении, я хотел бы просто использовать replaceAll с этим регулярным выражением .*?(\d+)$:

String regex = ".*?(\\d+)$";

String strResult1 = str.replaceAll(regex, "$1");
System.out.println(!strResult1.isEmpty() ? "result " + strResult1 : "no result");

String strResult2 = str1.replaceAll(regex, "$1");
System.out.println(!strResult2.isEmpty() ? "result " + strResult2 : "no result");

String strResult3 = str2.replaceAll(regex, "$1");
System.out.println(!strResult3.isEmpty() ? "result " + strResult3 : "no result");

Если результат пустой, то у вас нетлюбое число.

Выходы

result 1
result 2
result 69
0 голосов
/ 23 октября 2018

Вот однострочная строка, использующая String#replaceAll:

public String getDigits(String input) {
    String number = input.replaceAll(".*/(?:a-b|c-d|e-f)/[^/]*?(\\d+)$", "$1");
    return number.matches("\\d+") ? number : "no match";
}

System.out.println(getDigits("foo.com/Samsung-Galaxy/9090/c-d/69"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/a-b/some other text/1"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/9090/a-b/69ace"));

69
no match
no match

Это работает с предоставленными вами примерами ввода.Обратите внимание, что я добавил логику, которая будет отображать no match для случая, когда конечные цифры не могут быть сопоставлены с вашим шаблоном.В случае несоответствия мы обычно оставляем исходную строку ввода, которая не будет состоять из всех цифр.

0 голосов
/ 23 октября 2018

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

Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");

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

При использовании с matches() приведенный выше шаблон не требует явных привязок, ^и $.

Подробности

  • .* - любые 0+ символов, кроме символов разрыва строки, как можно больше
  • / - самый правый /, за которым следуют последующие подшаблоны
  • (?:a-b|c-d|e-f) - группа без захвата, соответствующая любой из альтернатив внутри: a-b, c-d или e-f
  • / - / char
  • [^/]*? - любые символы, кроме /, как можно меньше
  • ([0-9]+) - Группа 1:одна или несколько цифр.

Java demo :

List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");
for (String s : strs) {
    Matcher m = pattern.matcher(s);
    if (m.matches()) {
        System.out.println(s + ": \"" + m.group(1) + "\"");
    }
}

Подход с заменой с использованием того же регулярного выражения с добавленными якорями:

List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
String pattern = "^.*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)$";
for (String s : strs) {
    System.out.println(s + ": \"" + s.replaceFirst(pattern, "$1") + "\"");
}

См. еще одну демонстрацию Java .

Вывод:

foo/bar/Samsung-Galaxy/a-b/1: "1"
foo/bar/Samsung-Galaxy/c-d/1#P2: "2"
foo.com/Samsung-Galaxy/9090/c-d/69: "69"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...