9

近くに別のテキストブロックがない場合は、テキストを一致させようとしています。たとえば、前にない"bar"場合は一致させたいと思います。この正規表現でネガティブルックビハインドを使用して、直前にない場合は"foo"一致させることができます。"bar""foo"

/(?<!foo)bar/

しかし、私も一致しないのが好き"foo 12345 bar"です。私は試した:

/(?<!foo.{1,10})bar/

ただし、ワイルドカードと範囲を使用すると、Rubyでは無効な正規表現のように見えます。私は問題について間違って考えていますか?

4

2 に答える 2

13

あなたはそれについて正しい方法で考えています。しかし残念なことに、後読みは通常固定長です。唯一の大きな例外は、.NET の正規表現エンジンです。これにより、後読み内で反復量指定子を使用できます。ただし、先読みではなく、否定的な後読みのみが必要なためです。あなたのためのハックがあります。文字列を逆にして、一致を試みます。

/rab(?!.{0,10}oof)/

次に、一致の結果を逆にするか、一致する位置を文字列の長さから差し引きます。

あなたが与えた正規表現から、これは実際に必要なものの単純化されたバージョンにすぎないと思います。もちろん、barそれ自体が複雑なパターンである場合は、それを正しく反転させる方法についてさらに検討する必要があります。

パターンが可変長の後読みと先読みの両方を必要とする場合、これを解決するのが難しくなることに注意してください。また、あなたの場合、後読みを複数の可変長のものに分解することも可能です(どちら+も使用しないため*):

/(?<!foo)(?<!foo.)(?<!foo.{2})(?<!foo.{3})(?<!foo.{4})(?<!foo.{5})(?<!foo.{6})(?<!foo.{7})(?<!foo.{8})(?<!foo.{9})(?<!foo.{10})bar/

でも、それだけじゃないですよね?

于 2012-11-30T19:23:35.990 に答える
4

m.buettner が既に言及しているように、Ruby 正規表現の後方後読みは固定長でなければならず、そのようにドキュメントに記載されています。したがって、量指定子を後読み内に置くことはできません。

一度にすべてをチェックする必要はありません。正規表現一致の複数のステップを実行して、必要なものを取得してください。fooの 1 つのインスタンスの前に が存在すると、bar別の があるかどうかに関係なく、条件が破られると仮定するとbar

string.match(/bar/) and !string.match(/foo.*bar/)

例に必要なものを提供します。

で試合を成功させたい場合はbar foo bar、これを行うことができます

string.scan(/foo|bar/).first == "bar"
于 2012-11-30T21:26:43.147 に答える