質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

1488閲覧

Rubyの正規表現で以下の条件にマッチしたものを引っ張ってきたいです。

dongw

総合スコア119

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/07/26 07:38

文字列

aaaaaaaaatype:ataribbbbbbbbbbbbbbbtype:hazureccccccccccccccccccccccccctype:atariddddddddddddd(以下繰り返し)

このような文字列から
一番最初に出現するtype:がatariだった場合だけを正規表現で判定
2回目以降に出現するtype:atariや、1回目のtype:がatari以外だった場合はマッチさせない

という条件を考えています。

上記の条件で正規表現を書いて1番目のtype:がatariだった場合だけに、
type:atariを抜き出して返す、という処理をしたいと思っています。
(1番目がatari以外だったらfalseで返す)

しかし実際に書いた所、type:atariだけを検索する正規表現だと2回目
のマッチでも合致してしまうなどうまく行きませんでした。

Rubyの正規表現でどう書けばいいか教えて頂けるとありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

Ruby2.4.1ならこう書けます

re = /^(?~type:)type:atari/ re.match?('aatype:atariaaatype:hazureaa') #=> true re.match?('aatype:hazureaaatype:atariaa') #=> false

(?~...)は2.4.1で追加された非包含演算子で、...の正規表現にマッチしない部分文字列にマッチします。

それ以前であれば

re = /^[^t]*(t[^y]*|ty[^p]*|typ[^e]*|type[^:]*)*type:atari/ re.match?('aatype:atariaaatype:hazureaa') #=> true re.match?('aatype:hazureaaatype:atariaa') #=> false

これでいいような気がします。

明らかに複雑なので、

str.match(/^.*?type:(.{5})/).to_a[1] == 'atari'

と文字列を取り出すのと判定は分離した方がわかりやすいと思います。

投稿2017/07/26 23:38

編集2017/07/26 23:44
suzukis

総合スコア1449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/27 00:04

おぉw Rubyだと正規表現だけでイケるんですね。 どっかで見たことあったんで、スッキリしました。
dongw

2017/08/01 08:11

回答ありがとうございます! (?~...)は知りませんでした・・・勉強になります。 ちょうどRuby2.4.1でやっているのでこちらも使えますね。ありがとうございます!
guest

0

Ruby

1str = "~~~~~~~" 2if str.scan(/type:(.....)/).dig(0,0) == "atari" 3 puts "先頭がatari" 4end

投稿2017/07/26 08:44

otn

総合スコア84712

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dongw

2017/08/01 08:03

回答ありがとうございます! scanとdigを組み合わせ判定する方法は思い浮かびませんでした。 こちらの方法も勉強になります!
guest

0

少し要件とはズレますが、以下でどうでしょうか?
/(type:atari)|type:./
Group 1 を見ることになりますが、type:atari の場合のみを抽出できます。

投稿2017/07/26 08:30

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2017/07/26 08:47

シンプルですね!!
退会済みユーザー

退会済みユーザー

2017/07/26 09:23

ありがとうございます! 実は、要件通りの正規表現がかけると思って始めたんですけど、ダメでした。。。 最初に出る type を限定しないといけないので、妥協の結果です^^;
dongw

2017/08/01 08:02

回答ありがとうございます! 確かにグループでマッチさせてgroup1を取得すれば行けそうですね! 今回の要件だと/(type:atari)/でもいいのかな・・・?
dongw

2017/08/01 08:04

あ、1回目にtype:atari じゃない場合もあるので回答頂いた記述じゃないとダメでしたね
退会済みユーザー

退会済みユーザー

2017/08/01 09:04

正規表現での実装は、suzukis さんのモノがきれいで良さ気です^^
guest

0

Ruby

1str = 'aaaaaaaaatype:ataribbbbbbbbbbbbbbbtype:hazureccccccccccccccccccccccccctype:atariddddddddddddd' 2 3str =~ /(type:.{5})/ 4 5p $1 == 'type:atari' ? $1 : false 6

全てのtype:atariを取り出すバージョン。

Ruby

1str = 'aaaaaaaaatype:ataribbbbbbbbbbbbbbbtype:hazureccccccccccccccccccccccccctype:atariddddddddddddd' 2 3str =~ /(type:.{5})/ 4 5p $1 == 'type:atari' ? str.scan($1) : false 6

投稿2017/07/26 09:02

編集2017/07/26 09:12
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dongw

2017/08/01 08:07

回答ありがとうございます! こちらもグループで判定させる方法ですね! 一番目に引っかっかったものを判定させればいいということですね。 勉強になります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問