регулярное выражение час:минута (час › 24)

Я хочу проверить и извлечь часы и минуты из строки, используя Regex в .NET. Просто чтобы восстановить два числа, разделенные (или не разделенные) :. Допустимый формат h:m или m. Непринято :m, h:.

РЕДАКТИРОВАТЬ: Следует отметить, что количество часов может превышать 23 до... 32.

Переполнение для часов (более 32) и минут (более 59) я буду делать после восстановления значений (int.Parse)


* просто для удовольствия может быть, есть относительно простое регулярное выражение, которое могло бы фильтровать также >32 для часов и >59 для минут (для минут это может быть [0-5]*[0-9], для часов не знаю)?


person serhio    schedule 04.01.2010    source источник
comment
В Java вы просто проанализируете строку в объект Date, используя немягкий синтаксический анализатор, и поймаете исключение (которое означает сбой). Что-то не существует в .NET?   -  person BalusC    schedule 04.01.2010
comment
Извините, но, пожалуйста, задайте вопрос. Вы никогда не научитесь программировать без определенного подхода проб и ошибок. Как только вы действительно застряли, все будут рады помочь вам!   -  person moritz    schedule 04.01.2010
comment
@moritz: это не изучение кода. Просто сложное регулярное выражение IMO.   -  person serhio    schedule 04.01.2010
comment
Я советую вам прочитать больше о регулярных выражениях, потому что это простая задача. Перейдите на regular-expressions.info, и когда вы почувствуете себя немного комфортно в этой теме, вы можете использовать такие инструменты, как txt2re.com. Не меняйте порядок, потому что иначе вы все равно не сможете написать никаких регулярных выражений — вы всегда должны понимать, что пишете.   -  person przemoc    schedule 04.01.2010
comment
@przemoc: спасибо за советы и ссылки. Я знаю первую, интересна первая. Однако есть много людей, которые спрашивают о регулярных выражениях, если вы отправите им всем expressions.info или ссылку на регулярное выражение MSDN, я не знаю, удовлетворит ли ответ всех. вы также можете дать им википедию или вообще доступ в Интернет и сказать им: ищите и учитесь :) однако спасибо.   -  person serhio    schedule 04.01.2010
comment
Грубая сила! (00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |15|16|17|18|19|20|21|22|23):(00|01|02|03|04|05|06|07|08|09|0|1|2|3|4 |5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29 |30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54 |55|56|57|58|59)   -  person Tamas Czinege    schedule 04.01.2010
comment
@DrJokepu: : не обязательно :D   -  person serhio    schedule 04.01.2010


Ответы (4)


Вы твердо настроены на регулярное выражение? Потому что DateTime.Parse здесь было бы гораздо проще и мощнее.

 DateTime dt = DateTime.Parse("12:30 AM");

Затем DT дает вам все, что вам нужно знать о времени. DateTime.TryParse() может быть лучше, если вы менее уверены, что это строка времени.

person Matt Greer    schedule 04.01.2010
comment
У тебя может быть причина. Прежде всего, мне нужно исключить любое влияние местной Культуры. Во-вторых, мой вопрос был больше связан с упражнением Regex. - person serhio; 04.01.2010
comment
Затем вы должны пройти CultureInfo.InvariantCulture. Смотрите мой ответ. - person SLaks; 04.01.2010
comment
Я забыл одну мелочь: maxhour = 32 :) - person serhio; 11.01.2010

(?:(\d\d?):)?([0-5][0-9])

Если вы хотите проверить часы:

(?:([01]?[0-9]|2[0-3]):)?([0-5][0-9])

EDIT: проверено и исправлено.


Однако лучший способ сделать это с помощью DateTime.ParseExact, например: (Проверено)

TimeSpan time = DateTime.ParseExact(
    input, 
    new string[] { "HH:mm", "H:mm", "mm", "%m" }, //The % is necessary to prevent it from being interpreted as a single-character standard format.
    CultureInfo.InvariantCulture, DateTimeStyles.None
).TimeOfDay;

Для проверки можно использовать TryParseExact.

person SLaks    schedule 04.01.2010
comment
Я протестировал регулярные выражения и нашел несколько ошибок, которые исправил. - person SLaks; 04.01.2010
comment
@Да. в качестве других исправлений я мог бы упомянуть DateTime time и new string[]. Однако спасибо, я ценю ответ и с точки зрения регулярного выражения, и с точки зрения dateTime. - person serhio; 04.01.2010
comment
time это TimeSpan. (Обратите внимание на свойство TimeOfDay) new [] { } — это синтаксис C# 3.0; если вы используете C# 2.0, вам нужно будет написать new string[] { }. - person SLaks; 04.01.2010
comment
Просто 5 не будет анализировать m DateTime... Я использовал bool result = DateTime.TryParseExact( "5", new string [] { "HH:mm", "H:mm", "mm", "m" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); - person serhio; 04.01.2010
comment
Вам нужно использовать %m. См. здесь:msdn.microsoft.com/en-us/library/< /а> - person SLaks; 04.01.2010
comment
yah bool result = DateTime.TryParseExact( 5, новая строка [] {%H:%m, H:%m, %m}, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt); работал! - person serhio; 04.01.2010
comment
да, у меня есть еще одна причина использовать регулярное выражение вместо DateTime.Parse - количество часов в моем случае будет более 24 -- 32. - person serhio; 11.01.2010
comment
?Regex.IsMatch(33:59, (?:([012]?[0-9]|3[01]):)?([0-5][0-9]) ) Верно - нехорошо... - person serhio; 11.01.2010

Вот строка регулярного выражения. Вы можете получить доступ к именованным группам захвата «часы» и «минуты». Используйте флаги «ExplicitCapture» и «Singleline».

@"^((?‹часы>[0-9]{1,2}):)?(?‹минуты>[0-9]{1,2})$"

Вы можете протестировать регулярные выражения здесь: http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

Как уже упоминалось, вызов синтаксического анализа DateTime может быть лучше, если вам не нужно проверять, разрешена ли только эта форма.

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

person Lilith River    schedule 04.01.2010
comment
хм... с вашего тестового сайта: Ошибка: синтаксический анализ ^((?[0-9]{1,2})\:)?(?[0-9]{1,2})$ - Нераспознанная конструкция группировки. - person serhio; 04.01.2010
comment
Спасибо - исправил. Мои угловые скобки потерялись при переводе. - person Lilith River; 05.01.2010

Наконец, код для проверки (до 32), а также получения значений (версия vb.net):

Dim regexHour As New Regex( _ 
   "((?<hours>([012]?\d)|(3[01]))\:)?(?<minutes>[0-5]?\d)", _
    RegexOptions.ExplicitCapture)
Dim matches As MatchCollection = regexHour.Matches(value)

If matches.Count = 1 Then
  With matches(0)
    ' (!) The first group is always the expression itself. '
    If .Groups.Count = 3 Then ' hours : minutes '
      strHours = .Groups("hours").Value
      If String.IsNullOrEmpty(strHours) Then strHours = "0"
      strMinutes = .Groups("minutes").Value
    Else ' there are 1, 3 or > 3 groups '
      success = False
    End If
  End With
Else
  success = False
End If

Спасибо всем, кто внес свой вклад в этот ответ!

person serhio    schedule 11.01.2010
comment
Я думаю, вы перепутали квантификатор ? (ноль или одно повторение) с квантификатором * (ноль или более повторений). - person Gumbo; 10.03.2010
comment
@Гамбо: Да. Спасибо! Обновлено. - person serhio; 11.03.2010