Час получения регулярного выражения

У меня есть это REGEX, чтобы проверить абзац и получить оттуда некоторые данные.

([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2})[\s\D\s]+([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2}),(.+),(\s\w{1,2} de [\wç]+ de \d{4})?(\s\w+ \d{1,2}, \d{4})?$

Мне нужно получить час, название и дату этого типа текстов:

ПРИМЕР 1. В этом примере проблема возникает из-за числа 130, и я не могу получить первый час.

1:30pm to 4:30pm, Aniversário amigo matteo, Ana Montoya, Accepted, Location: Kids Buffet Infantil
Rua do Triunfo, 130, Brookling, Hello - SP, 04602-005, Brasil, November 23, 2022

ПРИМЕР 2: Это работает правильно

8am to 9:30am, All Hearts meeting, Ana Montoya, Accepted, Location: https://us02web.zoom.us/j/1234?pwd=1234, November 21, 2022

Получите два часа, текст заголовка и окончательную дату

В чем проблема? Я вижу 2 захваченных часа regex101.com/r/60w1uB/1

The fourth bird 18.11.2022 21:05

К вашему сведению, {0,1} можно заменить на ?, что означает, что шаблон не является обязательным.

Barmar 18.11.2022 21:12

Будет ли ваша строка всегда иметь один и тот же формат, и вы ищете только ответ регулярного выражения? Кроме того, как вы определяете, что такое заголовок?

dale landry 18.11.2022 21:21
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
учебник по Javascript
учебник по Javascript
JavaScript - это язык программирования, который обычно используется для добавления интерактивности и других динамических функций на веб-сайты. Он...
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
Как использовать d3.js для рисования 2D SVG-элементов в приложении Angular?
D3.js - это обширная библиотека, используемая для привязки произвольных данных к объектной модели документа (DOM). Мы разберем основные варианты...
Освоение принципов SOLID в JavaScript: Пошаговое руководство
Освоение принципов SOLID в JavaScript: Пошаговое руководство
Принцип единой ответственности (SRP): класс должен иметь только одну причину для изменения. Другими словами, у него должна быть только одна...
JavaScript - For Loop
JavaScript - For Loop
Наиболее используемая компактная форма оператора цикла.
Неделя 1 - Карточки с временной шкалой
Неделя 1 - Карточки с временной шкалой
Поскольку это была первая неделя, я решил начать с простого. Предполагалось, что у меня будет временная шкала с несколькими карточками, которые можно...
1
3
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы добавили $ в конце, это означает, что ваше выражение должно соответствовать концу строки ($ соответствует сразу после последнего символа в строке).

1- Проблема может быть решена довольно просто, убрав $ в конце:

([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2})[\s\D\s]+([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2}),(.+),(\s\w{1,2} de [\wç]+ de \d{4})?(\s\w+ \d{1,2}, \d{4})?

2- И лучше добавить символ ^ слева, чтобы заставить выражение соответствовать началу (символ ^ соответствует позиции перед первым символом в строке)

^([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2})[\s\D\s]+([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2}),(.+),(\s\w{1,2} de [\wç]+ de \d{4})?(\s\w+ \d{1,2}, \d{4})?

3- Или добавив .* в конце регулярного выражения (перед $),

([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2})[\s\D\s]+([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2}),(.+),(\s\w{1,2} de [\wç]+ de \d{4})?(\s\w+ \d{1,2}, \d{4})?.*$

На самом деле поиск по регулярному выражению соответствует максимуму. Добавив .* в конце (перед символом $), он будет соответствовать максимальному значению справа, поэтому, как и сдвиг влево, будет сопоставлено первое вхождение.

4- Или все эти решения:

^([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2})[\s\D\s]+([0-9]{1,2}:{0,1}[0-9]{0,2}[a-z]{0,2}),(.+),(\s\w{1,2} de [\wç]+ de \d{4})?(\s\w+ \d{1,2}, \d{4})?.*$

Это отчаянно нуждается в поддерживающем объяснении.

Wyck 18.11.2022 22:55

Обновлено с объяснением

Ali ISSA 19.11.2022 01:58
Ответ принят как подходящий

Вот модифицированное регулярное выражение с вашими примерами входных строк:

[
  '1:30pm to 4:30pm, Aniversário amigo matteo, Ana Montoya, Accepted, Location: Kids Buffet Infantil Rua do Triunfo, 130, Brookling, Hello - SP, 04602-005, Brasil, November 23, 2022',
  '8am to 9:30am, All Hearts meeting, Ana Montoya, Accepted, Location: https://us02web.zoom.us/j/1234?pwd=1234, November 21, 2022'
].forEach(str => {
  let m = str.match(/^(\d\d?(?::\d\d)?[ap]m) to (\d\d?(?::\d\d)?[ap]m), *([^,]+).* ([a-z]+ \d+, \d{4})/i);
  console.log(m);
});

Вывод:

[
  "1:30pm to 4:30pm, Aniversário amigo matteo, Ana Montoya, Accepted, Location: Kids Buffet Infantil Rua do Triunfo, 130, Brookling, Hello - SP, 04602-005, Brasil, November 23, 2022",
  "1:30pm",
  "4:30pm",
  "Aniversário amigo matteo",
  "November 23, 2022"
]
[
  "8am to 9:30am, All Hearts meeting, Ana Montoya, Accepted, Location: https://us02web.zoom.us/j/1234?pwd=1234, November 21, 2022",
  "8am",
  "9:30am",
  "All Hearts meeting",
  "November 21, 2022"
]

Объяснение регулярного выражения:

  • ^ -- якорь в начале строки
  • ( -- начало захвата группы 1
  • \d\d? -- 1 или 2 цифры
  • (?::\d\d)? -- необязательная группа без захвата для двоеточия и 2 цифр
  • [ap]m -- буквальный am или pm
  • ) -- захватить конец группы 1
  • to -- буквальный текст
  • (\d\d?(?::\d\d)?[ap]m) -- захватить группу 2, как указано выше
  • , * -- запятая и необязательные пробелы
  • ([^,]+) -- заголовок до следующей запятой
  • .* -- жадное сканирование до последнего пробела, за которым следует:
  • ([a-z]+ \d+, \d{4}) -- формат даты Mmmmm dd, yyyy
  • игнорировать флаг случая i

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