У меня есть это 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
Получите два часа, текст заголовка и окончательную дату
К вашему сведению, {0,1}
можно заменить на ?
, что означает, что шаблон не является обязательным.
Будет ли ваша строка всегда иметь один и тот же формат, и вы ищете только ответ регулярного выражения? Кроме того, как вы определяете, что такое заголовок?
Вы добавили $ в конце, это означает, что ваше выражение должно соответствовать концу строки ($ соответствует сразу после последнего символа в строке).
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})?.*$
Это отчаянно нуждается в поддерживающем объяснении.
Обновлено с объяснением
Вот модифицированное регулярное выражение с вашими примерами входных строк:
[
'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
)
-- захватить конец группы 1to
-- буквальный текст(\d\d?(?::\d\d)?[ap]m)
-- захватить группу 2, как указано выше, *
-- запятая и необязательные пробелы([^,]+)
-- заголовок до следующей запятой.*
-- жадное сканирование до последнего пробела, за которым следует:([a-z]+ \d+, \d{4})
-- формат даты Mmmmm dd, yyyy
i
В чем проблема? Я вижу 2 захваченных часа regex101.com/r/60w1uB/1