回答:
を使用scan
してトリックを行う必要があります:
string.scan(/regex/)
/(?=(...))/
。
一致するすべての文字列を検索するには、Stringのscan
メソッドを使用します。
str = "A 54mpl3 string w1th 7 numb3rs scatter36 ar0und"
str.scan(/\d+/)
#=> ["54", "3", "1", "7", "3", "36", "0"]
MatchData
Regexp match
メソッドによって返されるオブジェクトのタイプであるが必要な場合は、以下を使用します。
str.to_enum(:scan, /\d+/).map { Regexp.last_match }
#=> [#<MatchData "54">, #<MatchData "3">, #<MatchData "1">, #<MatchData "7">, #<MatchData "3">, #<MatchData "36">, #<MatchData "0">]
を使用する利点MatchData
は、次のような方法を使用できることですoffset
。
match_datas = str.to_enum(:scan, /\d+/).map { Regexp.last_match }
match_datas[0].offset(0)
#=> [2, 4]
match_datas[1].offset(0)
#=> [7, 8]
詳細については、次の質問をご覧ください。
特殊変数について読んで$&
、$'
、$1
、$2
Rubyであまりにも参考になります。
グループの正規表現がある場合:
str="A 54mpl3 string w1th 7 numbers scatter3r ar0und"
re=/(\d+)[m-t]/
Stringのscan
メソッドを使用して、一致するグループを見つけることができます。
str.scan re
#> [["54"], ["1"], ["3"]]
一致するパターンを見つけるには:
str.to_enum(:scan,re).map {$&}
#> ["54m", "1t", "3r"]
str.scan(/\d+[m-t]/) # => ["54m", "1t", "3r"]
より慣用的ですstr.to_enum(:scan,re).map {$&}
/(\d+)[m-t]/
でした:/\d+[m-t]/
書き込むことre = /(\d+)[m-t]/; str.scan(re)
はありません:同じですstr.scan(/(\d+)[mt]/)
が#>が得られますが、質問は[["" 54 "], [" 1 "], [" 3 "]]
ありませんでした"54m", "1t", "3r"]
。表現(グループを離れる)、どうすればよいですか?この意味で、読んで少し不可解な困難にもかかわらず可能な解決策であった:str.to_enum(:scan,re).map {$&}
使用できますstring.scan(your_regex).flatten
。正規表現にグループが含まれている場合、単一のプレーン配列で返されます。
string = "A 54mpl3 string w1th 7 numbers scatter3r ar0und"
your_regex = /(\d+)[m-t]/
string.scan(your_regex).flatten
=> ["54", "1", "3"]
正規表現は名前付きグループにすることもできます。
string = 'group_photo.jpg'
regex = /\A(?<name>.*)\.(?<ext>.*)\z/
string.scan(regex).flatten
gsub
MatchDataが必要な場合は、を使用することもできます。
str.gsub(/\d/).map{ Regexp.last_match }
your_regex = /(\d+)[m-t]/
を使用する必要がなくなりますflatten
。最後の例ではlast_match
、この場合はおそらく安全ですが、グローバルであり、を呼び出す前に正規表現が一致した場合は上書きされる可能性がありますlast_match
。その代わりに、使用におそらく安全ですstring.match(regex).captures # => ["group_photo", "jpg"]
かstring.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]
パターンやニーズに応じて、他の回答のように。