0

Ruby Quiz book の問題 #6 を解こうとしています。この問題は、正規表現クラスに対して呼び出される新しいメソッドを作成する必要があることを示しています。このメソッドbuild()では、整数または範囲を渡し、許可された数値を検出するために正規表現を生成する必要があります。

例えば:

lucky = Regexp.build(3, 7)
"7" =~ lucky # => true
"13" =~ lucky # => false
"3" =~ lucky # => true

month = Regexp.build(1..12)
"0" =~ month # => false
"1" =~ month # => true
"12" =~ month # => true

バグのあるバージョンを開発しましたが、期待どおりに動作しません。私の問題は、正しい正規表現を生成することです。私が Rubular で試したすべてのパターンは、本来あるべきものを取りません。たとえば、Regexp.build(1, 3, 5)次のようなパターンを取得しました。

/^1|3|5$/

これは機能し、 と に一致13ます515しかし、 orにも一致し13ます。

数値がそれらの間で結合しないようにする最良の方法は何ですか?

- - 編集

グループを使用すると、適切に機能するようになりました。とにかく、範囲を表す正規表現を取得する方法はありますか? たとえば、前の例を維持します。

lucky = Regexp.build(1..12)
"7" =~ lucky # => true
"13" =~ lucky # => false
"0" =~ lucky # => false
"5" =~ lucky # => true

Regexp.build によって生成される正規表現は、1 から 12 までのすべての値と一致する必要がありますが、それ以上は一致しません。私はウェブを検索してきましたが、この種の正規表現をプログラムで生成するのは複雑であることがわかりました。このタスクの具体的または事前定義された方法はありますか?

http://utilitymill.comにはそれを実現するための再帰関数がありますが、ちょっと複雑だと思います。

4

4 に答える 4

2
/(^|\D)1(\D|$)|(^|\D)3(\D|$)|(^|\D)5(\D|$)/

この正規表現コードは 1 3 5 とは異なる方法で一致し、13 と 15 には一致しません。

私が何か誤解している場合は、あなたが何を望んでいるかを詳細に説明してください.

ありがとうございました

于 2013-09-26T18:28:05.880 に答える
1

ちょっとしたヒント:

/^1|3|5$/

意味

/^1/または/3/または/5$/

グループを調べます。それらは、代替の範囲に開始/終了アンカーが含まれていないことを確認するのに役立ちます。

于 2013-09-26T17:29:25.880 に答える
0

最初と最後にある単数形のアイテムを一致させたいとします。これは、括弧でグループ化することで実現できます。例えば:/^(1|3|5)$/

于 2013-09-26T17:31:42.123 に答える
0

問題は、パターンが単語内 (数内?) の一致を許可していることです。私はこれを使用します:

/\b(?:3|7)\b/

3、または7.

http://rubular.com/r/0rRUfXdlTJでテストされています。

このパターンは、スタンドアロンの値、または文字列に埋め込まれた数値で機能します。

\bつまり、非単語から単語への遷移が必要です。一言です[a-zA-Z0-9_]

テストの使用:

"7" =~ /\b(?:3|7)\b/   # => 0
"13" =~ /\b(?:3|7)\b/  # => nil
"3" =~ /\b(?:3|7)\b/   # => 0

"0" =~ /\b(?:1|2|3|4|5|6|7|8|9|10|11|12)\b/   # => nil
"1" =~ /\b(?:1|2|3|4|5|6|7|8|9|10|11|12)\b/   # => 0
"12" =~ /\b(?:1|2|3|4|5|6|7|8|9|10|11|12)\b/  # => 0

where=> 0は、最初の文字インデックスでパターンが一致し、nilミスしたことを意味します。

そうは言っても、範囲を強制するためにパターンを使用しようとはしません。受け入れ可能な IPv4 番号、またはさらに悪いことにIPv6番号をテストするために使用されるパターンを見てください。面白いことに、有効な電子メール アドレスのパターンを見てください。それらはすべて、有効な値を定義する仕様を持っていますが、それらを定義するためのパターンは複雑で、定命の人間の範囲を超えています。代わりに、パターンを使用して数字のように見えるものを見つけ、その値を抽出して、それが許容範囲内にあるかどうかをテストします。

たとえば、Ruby の Resolv::IPv4::Regex の IPv4 パターンは次のとおりです。

/\A((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\.((?x-mi:0
               |1(?:[0-9][0-9]?)?
               |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
               |[3-9][0-9]?))\z/

IPv6 のように値が長いと、さらに難しくなります。詳しくは、有効な IPv6 アドレスに一致する正規表現を参照してください。したがって、単純なことには正規表現を使用し、正規表現が得意とすることを利用することをお勧めします。つまり、パターンに一致する値を抽出し、追加のコードを使用して値が範囲内にあるか、真に有効であることを確認します。

于 2013-09-26T18:01:24.110 に答える