2015-04-15 6 views
3

Использование рубин 2,2Рубин str.match (регулярное выражение) возвращает MatchData, содержащий только первый согласованный пункт

У меня есть строки, как следующее:

  • Еженедельно во вторник и пятницу
  • Еженедельно в понедельник, Среда и суббота
  • Ежемесячно каждые 2 недели в понедельник

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

/\b(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)\b/ 

При попытке использовать String#match метод экземпляра по match_data не возвращает все матчи. Напр. пожалуйста, обратитесь к выходу irb, показанному ниже, в котором, когда строка Weekly on Tuesday and Friday сопоставлена ​​с вышеуказанным регулярным выражением, MatchData содержит только Tuesday. Я ожидал, что он также будет содержать Friday.

2.2.1 :001 > str = "Weekly on Tuesday and Friday" 
    => "Weekly on Tuesday and Friday" 
    2.2.1 :002 > regex = /\b(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)\b/ 
    => /\b(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)\b/ 
    2.2.1 :003 > str.match(regex) 
    => #<MatchData "Tuesday" 1:"Tuesday"> 
    2.2.1 :004 > match_data = str.match(regex) 
    => #<MatchData "Tuesday" 1:"Tuesday"> 
    2.2.1 :005 > match_data.captures 
    => ["Tuesday"] 

Может кто-нибудь, пожалуйста, объясните мне, почему MatchData содержит только первый согласованный срок, когда я не использовал никакого начало/конец якоря в моем Regex? Я уверен, что мое регулярное выражение пропускает что-то, но я не могу понять.

Примечание

Rubular показывает правильные группы соответствия для того же регулярное выражение, как можно видеть на http://rubular.com/r/XZmrHPkjEk

+0

Вы пытались использовать 'str.scan (/ \ b (понедельник | вторник | среда | четверг | пятница | суббота | воскресенье] \ b /)'? Это то, что вы ищете? http://ruby-doc.com/docs/ProgrammingRuby/html/ref_c_string.html#String.scan. –

+0

@stribizhev Да 'str.scan (regex)' возвращает желаемые результаты. Но мне нужно понять, почему 'str.match (regex)' не возвращает все совпадения. –

+0

Потому что это не предполагается? Соответствие Regexp # возвращает совпадение для регулярного выражения.Ваше регулярное выражение только ищет один день недели и подбирается как таковой. –

ответ

3

Кажется, что MatchData возвращаемый .match() метод возвращает только первый матч со всеми захваченными группами, если таковые имеются. Я только что протестировал его, и я смог получить только 1 матч с .match().

См Regular-Expressions.info детали:

Чтобы проверить, если конкретное регулярное выражение соответствует (части) строка, вы можете либо использовать = ~ оператор, вызовите метод объекта РегВыра матча(), например: напечатать «успех», если subject = ~/regex/или напечатать «успех», если /regex/.match(subject).

Кроме того, из here:

String.=~(Regexp) возвращается в исходное положение первого матча или ноль, если совпадение найдено не было

Чтобы получить все матчи, вам нужно использовать .scan() метод.