現在、文字列を複数の変数にrexpしようとしています。文字列の例:
ryan_string = "RyanOnRails: This is a test"
3つのグループで、この正規表現と一致させました。
ryan_group = ryan_string.scan(/(^.*)(:)(.*)/i)
各グループにアクセスするには、次のようにする必要があります。
ryan_group[0][0] (first group) RyanOnRails
ryan_group[0][1] (second group) :
ryan_group[0][2] (third group) This is a test
これはかなりばかげているようで、私は何か間違ったことをしているように感じます。私はこのようなことをすることができると期待されるでしょう:
g1, g2, g3 = ryan_string.scan(/(^.*)(:)(.*)/i)
これは可能ですか?それとも私がそれをやっているよりも良い方法がありますか?
あまり意味がないので、scan
は必要ありません。 String#match
を使用してMatchData
オブジェクトを返し、#captures
を呼び出してキャプチャの配列を返すことができます。このようなもの:
#!/usr/bin/env Ruby
string = "RyanOnRails: This is a test"
one, two, three = string.match(/(^.*)(:)(.*)/i).captures
p one #=> "RyanOnRails"
p two #=> ":"
p three #=> " This is a test"
一致するものが見つからない場合、String#match
はnilを返すので、このようなものがより適切に機能することに注意してください。
if match = string.match(/(^.*)(:)(.*)/i)
one, two, three = match.captures
end
scan
はこれにはほとんど意味がありません。それはまだ仕事をします、あなたは最初に返された配列を平らにする必要があります。 one, two, three = string.scan(/(^.*)(:)(.*)/i).flatten
代わりに Match または=〜を使用すると、単一の一致が得られ、一致データに同じ方法でアクセスするか、特別な一致変数$ 1、$ 2、$ 3を使用できます
何かのようなもの:
if ryan_string =~ /(^.*)(:)(.*)/i
first = $1
third = $3
end
キャプチャした一致に名前を付けることができます
string = "RyanOnRails: This is a test"
/(?<one>^.*)(?<two>:)(?<three>.*)/i =~ string
puts one, two, three
文字列と正規表現の順序を逆にすると機能しません。
良いアイデアかどうかを判断する必要がありますが、Ruby regexpは(自動的に)ローカル変数を定義できます!
この機能が素晴らしいのか、まったく夢中なのかはまだわかりませんが、正規表現でローカル変数を定義できます。
ryan_string = "RyanOnRails: This is a test"
/^(?<webframework>.*)(?<colon>:)(?<rest>)/ =~ ryan_string
# This defined three variables for you. Crazy, but true.
webframework # => "RyanOnRails"
puts "W: #{webframework} , C: #{colon}, R: #{rest}"
( http://Ruby-doc.org/core-2.1.1/Regexp.html を見て、「ローカル変数」を検索してください)。
注:コメントで指摘したように、@ toonsend( https: //stackoverflow.com/a/21412455 )。私は「盗む」とは思いませんが、もしあなたが称賛と公正であり、最初の答えを尊重したいなら、気軽に:)動物に害を与えないことを望みます。
scan()
は、文字列内で正規表現に一致しないすべての一致を検出するため、予想されるようにグループの配列を返す代わりに、配列の配列を返します。
おそらくmatch()
を使用してから、MatchData#captures
を使用してキャプチャの配列を取得することをお勧めします。
g1, g2, g3 = ryan_string.match(/(^.*)(:)(.*)/i).captures
ただし、次の場合はscan()
でこれを行うこともできます。
g1, g2, g3 = ryan_string.scan(/(^.*)(:)(.*)/i)[0]