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

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

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

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

Q&A

解決済

5回答

2038閲覧

01, 0011, 000111....にマッチする正規表現の書き方

ivezuki

総合スコア33

Ruby

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

0グッド

6クリップ

投稿2014/10/07 15:12

タイトルの通りなのですが、01, 0011, 000111...のように0と1の数が同じ数になるような正規表現をrubyで作りたいのですが、上手く作れません。

方法がわかる方、ご教授お願いします。

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

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

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

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

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

guest

回答5

0

ベストアンサー

部分式呼び出し(再帰パターン)を使って、/\A(?<a>0\g<a>*1)\z/ ですかね。
文字列全体にマッチするかでなく、文字列の一部に含まれるかだと、文字列の先頭の場合、文字列の途中の場合、文字列の末尾の場合の3パターンに場合分けして | で繋ぐか、

lang

1/[^0](?<a>0\g<a>*1)[^1]/ =~ "X#{str}X"`

のよう対象文字列の前後に0でも1でもない物を付加して常に「文字列の途中」にするか。

投稿2014/10/08 01:13

otn

総合スコア84421

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

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

k.tada

2014/10/08 01:55

こんな方法があったんですね。正規表現の再帰パターン初めて知りました。
guest

0

試してみましたが、正規表現だけとなると難易度が高いですね、わたしにはできませんでした

target = '00001111100110011000111001' regex = /(0+)(1+)/ p target.scan(regex) p result = target.scan(regex).reject{|x| x.count('0') != x.count('1') } p result.map(&:join) # => [["0000", "11111"], ["00", "11"], ["00", "11"], ["000", "111"], ["00", "1"]] # => [["0000", "11111"], ["00", "11"], ["00", "11"], ["000", "111"]] # => ["000011111", "0011", "0011", "000111"]

正規表現には試行錯誤がつきもの。下記リンク先で正規表現の動作を確認することが出来ます

Link


(少し気になりましたが、"なぜ" この正規表現でのマッチをしたいのですか。正規表現に代わる方法がほかの回答者から得られるかもしれません)

投稿2014/10/07 18:48

gouf

総合スコア2321

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

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

0

文字列の途中のときは

lang

1/(?<!0)(?<a>0(\g<a>)*1)(?!1)/

でもいけそうですね。

投稿2014/10/09 11:15

yamc18

総合スコア14

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

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

0

正規表現というのは、もともと形式言語理論という理論の中で、正規言語を表すためのものです。
ご質問の文字列の集合は、正規言語ではありません。
つまり、理論的には、正規表現で表すことはできないということになります。

これは、あくまで形式言語理論の正規表現で表せないということなので、Rubyの正規表現では、
もしかしたら表現できる可能性は否定できません。
しかし、おそらく無理なのではないかと思います。

他の回答者の方が言っておられるように、他の手段を用いたり、できればもっと条件をつけたりするのが
簡単ではないでしょうか。

投稿2014/10/08 00:56

JohnSmith

総合スコア198

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

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

0

パターンの最長を押さえられるなら、
01, 0011, ... のパターンを個々に列挙してしまうことも考えられます。

lang

1target = '00001111100110011000111001' 2pat = /(0{5}1{5})|(0{4}1{4})|(0{3}1{3})|(0{2}1{2})|(01)/ 3 4target.scan(pat).flatten.compact # => ["00001111", "0011", "0011", "000111", "01"]

pat の生成を手で書くのではなく、プログラムで生成するようにすればもっと汎用的になります。

投稿2014/10/07 22:11

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問