@ spickermann использует положительный взгляд за и положительный взгляд и делает .*
не жадным, добавляя знак вопроса.Это мое предпочтение, но я упомяну другой нормальный способ сделать это, который использует группу захвата, а затем способ, который не создает промежуточный массив.
string = "hello glass car [clock][flower] candy [apple]"
As
string.scan(/\[(.*?)\]/)
#=> [["clock"], ["flower"], ["apple"]]
мы бы написали
string.scan(/\[(.*?)\]/).flatten.each { |word| puts "#{word} have" }
clock have
flower have
apple have
или
string.scan(/\[(.*?)\]/).each { |(word)| puts "#{word} have" }
clock have
flower have
apple have
Обратите внимание, что если бы квалификатор non-greedy
был удален из регулярного выражения, мы получили бы следующее:
arr = string.scan(/\[(.*)\]/)
#=> [["clock][flower] candy [apple"]]
, то есть массив, содержащий один элемент, который является массивом, содержащим один элемент, строку
"clock][flower] candy [apple"
См. String # scan , в частности, ссылку на(захват) групп.
Если, как следует из вопроса, вы просто хотите распечатать результаты и вам не нужен массив ["clock", "flower", "apple"]
, вы можете просто написать следующее:
string.gsub(/(?<=\[).*?(?=\])/) { |word| puts "#{word} have" }
clock have
flower have
apple have
#=> "hello glass car [][] candy []"
или
string.gsub(/\[(.*?)\]/) { puts "#{$1} have" }
clock have
flower have
apple have
#=> "hello glass car candy "
, исключая возвращаемое значение.