开发者

Ruby's "hello world".scan(/(\w){2}/) is not the same as "hello world".scan(/\w{2}/)?

开发者 https://www.devze.com 2023-01-24 06:55 出处:网络
I thought I knew scan in Ruby: as if it is doing a single match, but repeat it for all results and put i开发者_开发技巧nto array?

I thought I knew scan in Ruby: as if it is doing a single match, but repeat it for all results and put i开发者_开发技巧nto array?

ruby-1.9.2-p0 > "hello world".scan(/\w{2}/)
 => ["he", "ll", "wo", "rl"] 

ruby-1.9.2-p0 > "hello world".scan(/(\w){2}/)
 => [["e"], ["l"], ["o"], ["l"]] 

How come the second line resulted that -- and how do you make it return the same result as line 1? (because sometimes we have to add () to the regex.


as a contract, with or without (), the following are the same:

ruby-1.9.2-p0 > "hello world"[/\w{2}/]
 => "he" 

ruby-1.9.2-p0 > "hello world"[/(\w){2}/]
 => "he" 


The parens create a match group. Try /(?:\w){2}/ instead.


I found something more:

scan seems to work using group if there is any, so that's why the behavior of the 2nd line was like that. (using the last matched content inside ( ) and use that in the results inside the array.)

As a test: (if there are multiple groups, then all groups go into one array)

ruby-1.9.2-p0 > "hello world".scan(/((\w){2})/)
 => [["he", "e"], ["ll", "l"], ["wo", "o"], ["rl", "l"]] 

This is a way to get it: alway add top level ( ), and use map to get the first element in array (ie, the top level match):

ruby-1.9.2-p0 > "hello world".scan(/((\w){2})/).map {|e| e.first}
 => ["he", "ll", "wo", "rl"]

But I would still like to find simpler answer...

0

精彩评论

暂无评论...
验证码 换一张
取 消