Что сплат делает здесь? - PullRequest
       17

Что сплат делает здесь?

3 голосов
/ 21 сентября 2009
match, text, number = *"foobar 123".match(/([A-z]*) ([0-9]*)/)

Я знаю, что происходит какое-то совпадение с регулярным выражением, но какую роль играет сплат в этом месте, и есть ли способ сделать это без сплата, чтобы это было менее запутанным?

Ответы [ 5 ]

5 голосов
/ 21 сентября 2009

Сплат разбивает результаты соответствия регулярному выражению (a MatchData с тремя группами: весь шаблон, буквы и цифры) на три переменные. Таким образом, мы в итоге:

match = "foobar 123"
text = "foobar"
number = "123"

Без восклицательного знака был бы только один результат (MatchData), поэтому Руби не знал бы, как назначить его трем отдельным переменным.

3 голосов
/ 22 сентября 2009

есть ли способ сделать это без сплата, чтобы он был менее запутанным?

Поскольку a,b = [c,d] - это то же самое, что и a,b = *[c,d], и сплат вызывает to_a для своего операнда, когда это не массив, вы можете просто явно вызвать to_a и не нуждаться в сплате:

match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/).to_a

Не знаю, менее ли это сбивает с толку, но без блефа.

3 голосов
/ 21 сентября 2009

В документации для MatchData есть хорошее объяснение:

Потому что to_a вызывается при расширении * переменная, есть полезный ярлык назначения для извлечения совпавшего поля. Это немного медленнее, чем доступ к полям напрямую (как промежуточный массив генерируется).

   all,f1,f2,f3 = *(/(.)(.)(\d+)(\d)/.match("THX1138."))
   all   #=> "HX1138"
   f1    #=> "H"
   f2    #=> "X"
   f3    #=> "113"
0 голосов
/ 21 сентября 2009

MatchData - это специальная переменная, для всех намерений и целей - массив (вид), поэтому вы также можете сделать это:

match, text, number = "foobar 123".match(/([A-z]*) ([0-9]*)/)[0..2]

Подробнее о специальной переменной MatchData

0 голосов
/ 21 сентября 2009

String.match возвращает объект MatchData, который содержит все совпадения регулярного выражения. Оператор splat разбивает этот объект и возвращает все совпадения отдельно.

Если вы просто запустите

"foobar 123".match(/([A-z]*) ([0-9]*)/)

в irb вы можете видеть объект MatchData с собранными совпадениями.

...