Ruby正規表現の最初の一致を返す


97

Rubyの文字列で正規表現一致を実行し、最初の一致でそれを短絡させる方法を探しています。

私が処理している文字列は長く、標準的な方法(matchメソッド)が全体を処理し、各一致を収集し、すべての一致を含むMatchDataオブジェクトを返すように見えます。

match = string.match(/regex/)[0].to_s

回答:


134

あなたは試すことができvariableName[/regular expression/]ます。これはirbからの出力例です:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders"
=> "erik kalle johan anders erik kalle johan anders"
irb(main):004:0> names[/kalle/]
=> "kalle"

これは試合を行っておらず、舞台裏で最初の結果を返していますか?
岐阜

7
さまざまな長さの文字列を使用してベンチマークを行い、Cソースを確認した後、Regex.matchは短絡し、最初の一致のみを見つけることがわかりました。
Daniel Beardsley、

3
きちんと、このショートカットについて知りませんでした。
Pierre

このショートカットに関するドキュメントはありますか?私は私が比較的単純なタスクだと思ったものを高低で検索し、これを見つけて初めて問題を解決しました。ありがとう!
dmourati 2013年

5
@dmouratiこの機能はString#[]に記載されています。ドキュメントについて質問していただきありがとうございます。ドキュメントを読んでいるときcaptureに、完全一致の代わりにキャプチャを返すことができるという引数が見つかりました。
ナマケモノ2014

68

あなたは使うことができます[]:(のようですmatch

"foo+account2@gmail.com"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"foo+account2@gmail.com"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"

4
最良の完全な回答
akostadinov

23

試合の存在のみが重要な場合は、

/regexp/ =~ "string"

どちらの方法でもmatch、最初のヒットのみを返し、scan文字列全体を検索します。したがって、もし

matchData = "string string".match(/string/)
matchData[0]    # => "string"
matchData[1]    # => nil - it's the first capture group not a second match

8

この機能がすばらしいのか、それともまったくおかしなのかはまだわかりませんが、正規表現でローカル変数を定義できます。

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

http://ruby-doc.org/core-2.1.1/Regexp.htmlから取得)。


素晴らしい機能!私が必要とするもの
RaphaMex

注意:regex =~ string", not when 文字列=〜regex`の場合にのみ機能します
クリストファー・オエズベク

2

正規表現(regex)は、有限状態マシン(FSM)にすぎません。

FSMは「この状態が可能かどうか」という質問に答えようとします。

一致が見つかるまで(成功)、またはすべてのパスが探索されて一致が見つからないまで(失敗)、パターンマッチの作成を試み続けます。

成功した場合、「この状態は可能かどうか」という質問です。「はい」と回答しました。したがって、これ以上の照合は必要なく、正規表現が返されます。

これについては、こちらこちらをご覧ください。

さらに:これ正規表現がどのように機能するかを示す興味深い例です。ここで、正規表現は、与えられた数が素数であるかどうかを検出するために使用されます。この例はperlにありますが、rubyで書くこともできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.