1

Rubyで遊び始めたばかりで、何かに行き詰まっています。casefold attributeインスタンス化された後にRegexpオブジェクトを変更するためのトリックはありますか?

私が試した最良のアイデアは次のとおりです。

irb(main):001:0> a = Regexp.new('a')
=> /a/
irb(main):002:0> aA = Regexp.new(a.to_s, Regexp::IGNORECASE)
=> /(?-mix:a)/i

しかし、以下のどれもうまくいかないようです:

irb(main):003:0> a =~ 'a'
=> 0
irb(main):004:0> a =~ 'A'
=> nil
irb(main):005:0> aA =~ 'a'
=> 0
irb(main):006:0> aA =~ 'A'
=> nil

私が理解できないことがここで起こっています。'i'は8行目でどこに行きましたか?

irb(main):07:0> aA = Regexp.new(a.to_s, Regexp::IGNORECASE)
=> /(?-mix:a)/i
irb(main):08:0> aA.to_s
=> "(?-mix:a)"
irb(main):09:0>

Ruby1.9.3を使用しています。

私はまた、以下のコードを理解することができません:なぜ戻るのかfalse

/(?i:a)/.casefold?      #=> false
4

3 に答える 3

2

の結果はto_s正規表現文字列そのものなので (区切り文字や外部フラグはありません)、フラグは(?i:...)式自体の内部で一時的に設定またはクリアする構文に変換されます。これにより、同じ文字列に一致Regexpする単純な呼び出しを介してオブジェクトを取り戻すことができます。Regexp.new(s)

残念ながら、ラッピングには、オブジェクトに設定されていないフラグを明示的にクリアすることが含まれます。したがって、最初の正規表現は文字列化されてその間の何かになります。(?:-i...)つまり、casefoldオプションは括弧の間で明示的にオフになります。オブジェクトに対してオンに戻しても効果はありません。

a.source代わりにa.to_s、フラグ設定なしで元の式だけを取得するために使用できます。

irb(main):001:0> a=/a/
=> /a/
irb(main):002:0> aA = Regexp.new(a.source, Regexp::IGNORECASE)
=> /a/i
irb(main):003:0> a =~ 'a'
=> 0
irb(main):004:0> a =~ 'A'
=> nil
irb(main):005:0> aA =~ 'a'
=> 0
irb(main):006:0> aA =~ 'A'
=> 0
于 2013-01-19T11:53:28.003 に答える
2

コンソール出力が示すようa.to_sに、部分式のオプションとして大文字と小文字の区別が含まれているため、次のようaAに定義されています

/(?-mix:a)/i

したがって、大文字と小文字を区別しない正規表現をルビーに要求していますが、その大文字と小文字を区別しない正規表現の唯一のものは、大文字と小文字の区別がオンになっている場合のグループであるため、最終的な効果は、「a」が大文字と小文字を区別して一致することです

于 2013-01-19T12:02:25.170 に答える
1

フレデリックがすでに説明しているようto_sに、正規表現を呼び出すと、その周囲に修飾子が追加され、大文字と小文字の区別などのプロパティが確実に保持されます。したがって、大文字と小文字を区別する正規表現を大文字と小文字を区別しない正規表現に挿入した場合でも、挿入された部分では大文字と小文字が区別されます。同様に、最初の引数が正規表現である場合、または正規表現でto_sを呼び出した結果である場合、Regexp.newに指定された修飾子は効果がありません。

この問題を解決するsourceには、の代わりに正規表現を呼び出しますto_s。とは異なりto_ssource何も追加せずに正規表現のソースを返すだけです。

aA = Regexp.new(a.source, Regexp::IGNORECASE)

私はまた、以下のコードを理解することができません:なぜfalseを返すのですか?

/(?i:a)/.casefold? 

グローバルではなくローカルにフラグ(?i:...)を設定するためです。iこれは、正規表現全体ではなく、括弧内の正規表現の一部にのみ適用されます。もちろん、この場合、正規表現全体が括弧内にありますが、のような方法に関する限り、それは問題ではありませんcasefold?

于 2013-01-19T12:22:20.717 に答える