#c# #regex
#c# #регулярное выражение
Вопрос:
Я пытаюсь создать регулярное выражение, которое соответствует этой строке {Дата ЧЧ: ММ: сс}, но вот в чем хитрость: ЧЧ, ММ и сс необязательны, но это должно быть «ЧЧ», а не просто «H» (то же самое относится к ММ и сс). Если отображается единственное «H», строка не должна совпадать.
Я знаю, что могу использовать H{2} для сопоставления с HH, но, похоже, я не могу использовать эту функциональность плюс ?
для сопоставления с нулем или один раз (ноль, потому что это необязательно, и максимум один раз).
Пока я делаю это (что, очевидно, не работает):
Regex dateRegex = new Regex(@"{Date H{2}?:M{2}?:s{2}?}");
Следующий вопрос. Теперь, когда у меня есть совпадение с первой строкой, я хочу взять только часть HH: MM: ss и поместить ее в другую строку (это будет формат для объекта TimeStamp).
Я использовал тот же подход, вот так:
Regex dateFormatRegex = new Regex(@"(HH)?:?(MM)?:?(ss)?");
Но когда я пытаюсь это сделать с «{Date HH: MM}», я не получаю никаких совпадений. Почему?
Если я добавлю пробел, подобный этому Regex dateFormatRegex = new Regex(@" (HH)?:?(MM)?:?(ss)?");
, я получу результат, но мне не нужен пробел… Я думал, что первую круглую скобку нужно было экранировать, но (
в этом случае это не сработает. Я думаю, потому что это не скобка, которая является частью строки для сопоставления, а ключевой символ.
Ответ №1:
(H{2})?
соответствует нулю или двум H
символам.
Однако, в вашем случае, запись его дважды была бы более читаемой:
Regex dateRegex = new Regex(@"{Date (HH)?:(MM)?:(ss)?}");
Кроме того, убедитесь, что нет доступных функций для того, что вы пытаетесь сделать. Синтаксический анализ дат довольно распространен , и большинство языков программирования имеют функции в своей стандартной библиотеке — я бы почти поставил на это 1 тысячу своей репутации .В NET тоже есть такие функции.
Комментарии:
1. Я создаю пользовательский небольшой «язык» для переименования файлов, дата здесь относится не к объекту DateTime, а к дате, содержащейся в пользовательском объекте.
2. Это отлично сработало с основной строкой, смотрите Мой обновленный вопрос об очень похожей проблеме, которая возникает сразу после этого.
3. Возможно, стоит использовать . В любом случае, библиотека NET.
Ответ №2:
В вашей правке вы упоминаете нежелательный начальный пробел в результате… чтобы проверить начальное или конечное условие вместе с вашим регулярным выражением, не включая это в результат, вы можете использовать функцию поиска регулярных выражений.
new Regex(@"(?<=Date )(HH)?:?(MM)?:?(ss)?")
(?<=…) — это шаблон поиска сзади.
Тестовый сайт регулярных выражений с этим примером.
Что касается ввода Date HH:MM:ss
, то оно будет соответствовать обоим регулярным выражениям (с обратным поиском или без него).
Но входные данные FooBar HH:MM:ss
все равно будут соответствовать простому регулярному выражению, но поиск сзади здесь завершится неудачей. Поиск не изменяет содержимое результата, но предотвращает ложные совпадения (например, этот второй ввод, который не является датой).
Более подробную информацию о регулярных выражениях и поиске можно найти здесь.
Комментарии:
1. Я не уверен, что понимаю цель этого шаблона lookbehind, не могли бы вы, пожалуйста, объяснить подробнее?