33

少しの正規表現のヘルプを探しています。「 foo」または「bar 」の文字列に一致する式を設計したいが、 「 foo」と「bar」の両方には一致しない

私が何かをするなら...

/((foo)|(bar))/

「 foobar 」にマッチします。私が探しているものではありません。では、どちらかの用語が存在する場合にのみ正規表現を一致させるにはどうすればよいですか?

ありがとう!

4

13 に答える 13

40

これは私が使用するものです:

/^(foo|bar){1}$/

参照: http://www.regular-expressions.info/quickstart.htmlの繰り返し

于 2011-12-02T19:57:57.510 に答える
20

正規表現言語がそれをサポートしている場合は、ネガティブルックアラウンドを使用してください:

(?<!foo|bar)(foo|bar)(?!foo|bar)

これは、「foo」または「bar」の直前または直後にない「foo」または「bar」と一致します。これは、あなたが望んでいたことだと思います。

一致させようとしている文字列に他のトークン「foocuzbar」が含まれている可能性があるかどうかは、質問や例からは明らかではありません。その場合、このパターンは機能しません。

テストケースの結果は次のとおりです(「true」は、パターンが入力で見つかったことを意味します)。

foo: true
bar: true
foofoo: false
barfoo: false
foobarfoo: false
barbar: false
barfoofoo: false
于 2008-10-29T16:32:06.000 に答える
10

単一の正規表現でこれを行うことができますが、読みやすくするために次のようなことをお勧めします...

(/foo/ and not /bar/) || (/bar/ and not /foo/)
于 2008-10-29T15:11:08.923 に答える
3

「foo」と「bar」以外のコンテンツ、または一方が存在しない場合の一方の繰り返しに関する動作を指定していません。たとえば、 「 food」または「barbarian」は一致する必要がありますか?

「foo」または「bar」のいずれかのインスタンスを1つだけ含むが、両方ではなく、同じインスタンスの複数のインスタンスを含まない文字列を、文字列内の他のインスタンスに関係なく一致させたいと仮定します(つまり、「food」は「野蛮人」は一致しません)、見つかった一致の数を返す正規表現を使用して、一致が1つだけ見つかった場合にのみ成功したと見なすことができます。例:Perlの場合:

@matches = ($value =~ /(foo|bar)/g)  # @matches now hold all foos or bars present
if (scalar @matches == 1) {          # exactly one match found
  ...
}

同じターゲットの複数の繰り返しが許可されている場合(つまり、「野蛮な」一致)、一致のリストを調べて、一致がすべて同じテキストの繰り返しであるかどうか、または他のオプションがあるかどうかを確認することで、この同じ一般的なアプローチを使用できます。も存在します。

于 2008-10-29T16:59:24.430 に答える
2

あなたは?を検討したいかもしれません 条件付きテスト。

(?(?=regex)then|else)

正規表現条件

于 2008-10-29T15:56:11.733 に答える
2

真の排他的 OR が必要な場合は、正規表現ではなくコードでそれを行います。パールでは:

/foo/ xor /bar/

しかし、あなたのコメント:

一致: "foo"、"bar" 非一致: "foofoo" "barfoo" "foobarfoo" "barbar" "barfoofoo"

排他的な or を探しているわけではないことを示します。あなたは実際には「/foo|bar/正確に1回一致しますか?」という意味です。

my $matches = 0;
while (/foo|bar/g) {
  last if ++$matches > 1;
}

my $ok = ($matches == 1)
于 2008-10-29T17:59:56.477 に答える
1

これが遅いエントリであることは承知していますが、探している可能性のある他の人を助けるために:

(/b(?:(?:(?!foo)bar)|(?:(?!bar)foo))/b)
于 2015-07-06T03:19:58.313 に答える
0

単語の境界を使用して、単一の単語を取得できます...

me@home ~  
$ echo "Where is my bar of soap?" | egrep "\bfoo\b|\bbar\b"  
Where is my bar of soap?  

me@home ~  
$ echo "What the foo happened here?" | egrep "\bfoo\b|\bbar\b"  
What the foo happened here?  

me@home ~  
$ echo "Boy, that sure is foobar\!" | egrep "\bfoo\b|\bbar\b"  
于 2008-10-29T16:44:27.910 に答える
0
\b(foo)\b|\b(bar)\b

そして、最初のキャプチャ グループのみを使用します。

于 2008-10-29T15:41:23.433 に答える
0

私はこのようなものを使用します。単語の周りのスペースをチェックするだけですが、 を使用する場合は\bまたは\Bを使用して境界線をチェックできます\w。これは「 foo 」または「 bar 」に一致するため、念のために空白も置き換える必要があります。(何かを交換していると仮定します。)

/\s((foo)|(bar))\s/
于 2008-10-29T15:15:55.717 に答える
0

これは単一の正規表現ではできないと思います。また、境界は、照合対象に応じて機能する場合と機能しない場合があります。

各正規表現に対して個別に照合し、結果に対して XOR を実行します。

foo = re.search("foo", str) != None
bar = re.search("bar", str) != None
if foo ^ bar:
    # do someting...
于 2008-10-29T15:23:32.067 に答える
0

私は正規表現コーチで試しました:

x foo y
x bar y
x foobar y

このオプションをチェックするgと、一致するたびに再度検索されるため、実際に 3 つの単語すべてに一致します。
この動作が望ましくない場合は、式を固定できます。たとえば、単語の境界でのみ一致します。

\b(foo|bar)\b

問題 (データがどのように見えるか) についてより多くのコンテキストを提供すると、より良い答えが得られる可能性があります。

于 2008-10-29T15:27:36.690 に答える