web-dev-qa-db-ja.com

後に特定のサブストリングが続かないサブストリングに一致する正規表現

blahfooblahと一致するがblahfoobarblahとは一致しない正規表現が必要です

Barが後に続かない限り、fooとfooの周りのすべてにのみ一致するようにします。

私はこれを使用してみました:foo.*(?<!bar)これはかなり近いですが、blahfoobarblahと一致します。背後のネガティブな見方は、バーだけでなく、あらゆるものと一致する必要があります。

私が使用している特定の言語は、Clojureで、Java内部で正規表現を使用しています。

編集:より具体的には、blahfooblahfoobarblahではなくblahfoobarblahblahを渡す必要もあります。

97
Rayne

試してください:

/(?!.*bar)(?=.*foo)^(\w+)$/

テスト:

blahfooblah            # pass
blahfooblahbarfail     # fail
somethingfoo           # pass
shouldbarfooshouldfail # fail
barfoofail             # fail

正規表現の説明

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    bar                      'bar'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    .*                       any character except \n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    foo                      'foo'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    \w+                      Word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

その他の正規表現

barの直後にあるときにfooのみを除外する場合は、次を使用できます。

/(?!.*foobar)(?=.*foo)^(\w+)$/

編集

質問を具体的にするために更新しました。

/(?=.*foo(?!bar))^(\w+)$/

新しいテスト

fooshouldbarpass               # pass
butnotfoobarfail               # fail
fooshouldpassevenwithfoobar    # pass
nofuuhere                      # fail

新しい説明

(?=.*foo(?!bar))は、fooが検出されることを保証しますが、直接追跡されませんbar

132
maček

fooで始まらない何かが続くbarに一致させるには、試してください

foo(?!bar)

ネガティブな後読みを使用したバージョンは、「fooの後にbarで終わらないものが続く」と効果的に一致します。 .*barblahのすべてに一致し、(?<!bar)lahを振り返り、barと一致しないことを確認しますが、一致しないため、パターン全体が一致します。

48
stevemegson

代わりに否定的な先読みを使用します。

\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*

これは私のために働いた、それが役立つことを願っています。幸運を!

2
Audie

文字列全体ではなく、文字列内のすべての単語と一致するように動作することを提案するコメントを書きました。

これらすべてをコメントでつぶすのではなく、新しい回答として投稿しています。

新しい正規表現

/(?=\w*foo(?!bar))(\w+)/

サンプルテキスト

foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu needsfoo

一致する

foowithbar fooevenwithfoobar foohere butfooisokherebar needsfoo

1
maček

特定の一致リクエストは次の方法で照合できます。

_\w+foo(?!bar)\w+
_

これはblahfooblahfoobarblahと一致しますが、blahfoobarblahblahとは一致しません。

foo.*(?<!bar)の正規表現の問題は、fooの後の_.*_です。 barの後の文字を含む任意の文字と一致します。

0
dawg