Как оптимизировать шаблон регулярных выражений? - PullRequest
1 голос
/ 07 июня 2019

Я пытаюсь извлечь подстроку (ы) из текста и использую для этого регулярное выражение. Образец текста:

bla bla <b>1:30-2pm</b> bla bla <b>5-6:30am</b> some text <b>1-2:15am</b>

Я ищу записи временных рамок (1-30-2 вечера ...). Сделано их жирным шрифтом только для удобства чтения

Вот мое регулярное выражение:

\d{1,2}(:\d{1,2})? – \d{1,2}(:\d{1,2})?(am|pm)

фрагмент кода Java:

public static List<String> foo(String text, String regex) {
    List<String> entries = new ArrayList<>();
    Matcher matcher = Pattern.compile(regex).matcher(text);
    while (matcher.find()) {
        entries.add(matcher.group());
    }
    return entries;
}

Можете ли вы помочь мне оптимизировать шаблон регулярных выражений? Там могут быть некоторые случаи использования, которые я пропустил.

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Если мы хотим оптимизировать наше выражение, мы можем захотеть добавить дополнительные пробелы, на случай, если в наших входах могут быть какие-то дополнительные пробелы, кроме этого, ваше выражение выглядит великолепно:

(\d{1,2})(:\d{1,2})?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(am|pm)

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

Демо 1

Или:

(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)?(\s+)?-(\s+)?(\d{1,2})(:\d{1,2})?(\s+)?(am|pm)

Демо 2

, в зависимости от того, что будет необходимо.

Тест

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "(\\d{1,2})(:\\d{1,2})?(\\s+)?-(\\s+)?(\\d{1,2})(:\\d{1,2})?(am|pm)";
final String string = "bla bla 1:30-2pm bla bla 5-6:30am some text 1-2:15am\n"
     + "bla bla 1:30 - 2pm bla bla 5  - 6:30am some text 1 - 2:15am";

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

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

RegEx

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

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

1 голос
/ 07 июня 2019

Я предлагаю использовать регулярное выражение типа

String regex = "(?i)(?<!\\d)(?:0?[1-9]|1[0-2])(?::[0-5]\\d)?\\p{Pd}(?:0?[1-9]|1[0-2])(?::[0-5]\\d)?[ap]m\\b";

См. Демоверсию regex

Детали

  • (?i) - флаг без учета регистра (для значений AM, PM, am, pm и т. Д.)
  • (?<!\d) - цифры слева не допускаются
  • (?:0?[1-9]|1[0-2]) - необязательный 0, а затем цифра от 1 до 9 или 1, а затем 0, 1 или 2
  • (?::[0-5]\d)? - необязательная группа: цифра от 0 до 5, а затем любая одна цифра
  • \p{Pd} - любой дефис
  • (?:0?[1-9]|1[0-2])(?::[0-5]\d)? - см. Выше
  • [ap]m\b - a или p, а затем m и граница слова.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...