2015-10-10 2 views
0

Я пытаюсь создать регулярное выражение, которое вытаскивает первый раз из строки.Regex- Первый экземпляр времени в строке

Вопрос - формат времени не стандартизирован.

Вот возможные варианты.

':' with 1 hour digit before the ':' (ex. 9:00 pm) 
':' with 2 hour digits before the ':' (ex. 10:00pm) 
no minutes with with 1 hour digit (ex 9pm) 
no minutes with with 1 hour digit (ex 10pm) 

Кроме того, может или не может быть пробел перед «утра» или «вечера»

Вот пример строки.

7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text 

Я хотел бы эта строка вернуть "7:30 pm"

ответ

2

Вы не указали инструмент, который вы хотите использовать, здесь простая реализация с использованием sed:

echo '7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text' | sed 's/\([0-2]\?[0-9]\(:[0-5][0-9]\)\? *[ap]m\).*/\1/i' 

Legenda:

'[0-2]\?[0-9]'  match the hour (with 1 or 2 digits) 
'\(:[0-5][0-9]\)\?' match the minutes (optional) 
' *'     optional spaces 
'[ap]m'    match am,pm,AM,PM (also Am,aM,pM,Pm)* 
'.*'     match all the rest of the string 

В зависимости: внешний \(...\) создать группу всех abov e элементов (backreference), используемых позже в подстановочной части регулярного выражения \1. *: Последний /i модификатора сделать случай регулярок нечувствительного

Вы можете переписать все как стандартное PERL регулярного выражение:

/(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/ 

Маленький код рубина:

#!/usr/bin/env ruby 

input = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text" 
puts input[/(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/] 
+0

Это решение, похоже, отвечает на мой вопрос. У меня отсутствуют какие-либо крайние случаи? – mferg

+0

Я изменил, чтобы уменьшить пространственные ограничения (ноль или больше). На каком языке вы хотите использовать? Мы можем разделить регулярное выражение на группы и форматировать вывод определенным образом. Перед отправкой я пробовал все вышеперечисленные случаи. –

+0

Теперь он возвращается все время, а не только первое. Я использую рубин. – mferg

1

почти общее решение может быть достигнуто с помощью следующего выражения:

([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM)) 

Он считает захват группы, получая все присутствующие время строки на строку.

В JavaScript, это может быть проверено, как следующее:

var testTime = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text"; 

var timeRex = /([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM))/g; 

var firstTime = timeRex.exec(testTime)[0]; 

console.log(firstTime); 

Я действительно считаю, что есть более общее решение. Я попробую более стабильную, а затем опубликую ее здесь.

+0

утро | вечер | AM | PM explicitaly для решения, ориентированного на время, и не применять игнорирование для всего анализа. – apast

+1

Хорошая точка. Единственное, что я хочу вернуть только в первый раз.Как вы изменяете регулярное выражение для этого случая? Изменить. Пропустил индекс 0, чтобы получить первый случай. Как бы вы построили это в выражении? – mferg

+0

Для этого выражения следует использовать некоторую нежелательную технику. Попробуем что-нибудь подобное. – apast

2

Попробуйте это регулярное выражение:

(?i)\d{1,2}(?::\d{2})?\s*[ap]m 

Разъяснения:

(?i)   # insensitive case 
\d{1,2}   # one or two digits 
(?:    # optional group 
    :\d{2}  # the minutes 
)?    # end optional group 
\s*    # any spaces 
[ap]m   # "am" or "pm" 

Regex live here.

Надеется, что это помогает.

+0

Спасибо. Это отлично работает. Вы правы, мне нужно будет установить нечувствительный случай для AM AM AM PM PM Pm. Как настроить регулярное выражение для этого? – mferg

+0

Это решение принимает время с часами более 59 часов и 24 часа. Это немного не реально применяется. – apast

1

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

\d{1,2}\:?(?:\d{1,2}|)\s*[ap]m 
Смежные вопросы