Regex, чтобы получить последние цифры из строки и отсортировать их - PullRequest
2 голосов
/ 23 октября 2019

У меня есть список строк, по которым я хочу отсортировать их, используя последние цифры, присутствующие в строке, я пробовал это с использованием приведенного ниже кода, но по некоторым причинам, это выбор цифры, присутствующий перед последней цифрой, например,в строке "abc \ xyz 2 5" он выбирает 25 вместо 5, из-за чего неправильно сортирует. Могу ли я узнать, что не так в моем регулярном выражении?

Примечание. Мои последние две цифры всегда будут иметь метку времени, например 1571807700009 1571807700009.

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

public static void second() {   
List<String> strings = Arrays.asList("abc\\xyz 2 5", "abc\\\\xyz 1 8", "abc\\\\xyz 1 9", "abc\\\\xyz 1 7", "abc\\\\xyz 1 3");       
Collections.sort(strings, new Comparator<String>() {
        public int compare(String o1, String o2) {
            return (int) (extractInt(o1) - extractInt(o2));
        }

        Long extractInt(String s) {
            String num = s.replaceAll("\\D", "");
            return Long.parseLong(num);
        }
    });
    System.out.println(strings);

}

Вывод

[abc\\xyz 1 3, abc\\xyz 1 7, abc\\xyz 1 8, abc\\xyz 1 9, abc\xyz 2 5]

Ожидаемый вывод

[abc\\xyz 1 3, abc\\xyz 2 5, abc\\xyz 1 7, abc\\xyz 1 8, abc\xyz 1 9]

Ответы [ 4 ]

3 голосов
/ 23 октября 2019

Используя поток, сортируйте только по последнему целому числу, заменяя предыдущую часть строки пустой строкой. Вы также можете воспользоваться интерфейсом API Comparator, передав это значение методу сравнения.

   List<String> strings = Arrays.asList("abc\\xyz 2 5", "abc\\\\xyz 1 8",
      "abc\\\\xyz 1 9", "abc\\\\xyz 1 7", "abc\\\\xyz 1 3");

   strings = strings.stream()
       .sorted(Comparator.comparing(s -> Long.valueOf(s.replaceAll(".*\\s+", ""))))
       .collect(Collectors.toList());

   System.out.println(strings);
3 голосов
/ 23 октября 2019

Измените свой метод extractInt на этот, чтобы удалить из ввода все, кроме последнего числа:

Long extractInt(String s) {
    String num = s.replaceFirst("^.+\\b(\\d+)$", "$1");
    return Long.parseLong(num);
}

Это регулярное выражение соответствует жадному совпадению при запуске .+, чтобы убедиться, что совпадает самая длинная строка перед совпадением\d+ в конце после сопоставления границы слова, используя \b.

Это даст следующий вывод:

[abc\\xyz 1 3, abc\xyz 2 5, abc\\xyz 1 7, abc\\xyz 1 8, abc\\xyz 1 9]
2 голосов
/ 23 октября 2019

Если ваша цель - отсортировать строки путем сравнения только последней цифры, вам даже не нужно анализировать эту цифру как int или long. Предполагая, что ваши строки всегда имеют цифру в конце:

Function<String,String> lastDigit = s -> s.substring(s.length()-1);
List<String> strings = Arrays.asList("abc\\xyz 2 5", "abc\\\\xyz 1 8", "abc\\\\xyz 1 9", "abc\\\\xyz 1 7", "abc\\\\xyz 1 3"); 

System.out.println("Before sorting: " + strings);

strings.sort(Comparator.comparing(lastDigit));

System.out.println("After sorting: " + strings);

РЕДАКТИРОВАТЬ

Вы не сравниваете только последнюю цифру, как предполагалось в начале,но последний номер после последнего пробела. Если это так, используйте аналогичный подход ниже

Function<String,Long> lastNum = s -> Long.valueOf(s.substring(s.lastIndexOf(" ")+1));
List<String> strings = Arrays.asList("abc\\xyz 2 5", "abc\\\\xyz 1 8", "abc\\\\xyz 1 9", "abc\\\\xyz 1 7", "abc\\\\xyz 1 3"); 

System.out.println("Before sorting: " + strings);

strings.sort(Comparator.comparing(lastNum));

System.out.println("After sorting: " + strings);
1 голос
/ 23 октября 2019

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

Т.е.

strings = strings.stream().sorted(Comparator.comparing(
        s -> parseLong(s.substring(s.lastIndexOf(' ') + 1))
    )).collect(Collectors.toList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...