15

以下は疑似的な例であり、実際の正規表現ではありませんが、それでも私が意味するものの例です。


.* (anything)

-.* (NOT anything)

[A-Z] (Any letter A to Z, caps only)

-[A-Z] (NOT any letter A to Z, caps only)

編集:質問の逆を補体に変更しました。ここで変更が行われました:「正規表現をそれ自体の補完に変える」

4

6 に答える 6

16

まず第一に、あなたは正規表現の補集合を意味していると思います。それは逆ではありません。正規表現の逆はあまり意味がありません。しかし、関数として見ると、マッチャーの逆は、一致するすべての文字列を生成するジェネレーターであると言えるでしょう。一方、言語の補集合は、元の言語ではないすべての文字列です。

次に、ここで考慮すべき2つのビューがあります。

基本的に

正規言語の補集合は正規です。つまり、補集合の受け入れDFAを生成することが可能です(これは非常に簡単です。実際には、非受け入れ状態セットを受け入れ状態セットと交換するだけです)。そのようなDFAはすべて正規表現として表現できるため、原則として、実際にそのような正規表現を作成できます。

出発点として、正規言語に関するウィキペディアの記事を参照してください。

特に

最近のほとんどの言語で使用されている典型的なperl互換の正規表現構文には、補完演算子がありません。完全な正規表現の場合、負の先読み演算子を使用して同様の結果を得ることができます。一致しない(?!X)場合は文字列と正確に一致しますX。ただし、これは、通常の方法でより大きな正規表現の一部として使用できないため、補数演算子の代わりにはなりません。この正規表現は入力を「消費」しません。つまり、他の演算子と組み合わせて動作が異なります。

たとえば、数値文字列をとして一致させる場合、追加して追加[0-9]*する文字列全体を一致させるが、この手法を使用して記述する必要のある補数を見つけるには、このような否定された正規表現の通常の連結は次のようになります。私が知る限り、元に戻すことはできません。^$^(?!^[0-9]*$).*$

皮肉なことに、正規表現の実際の化身は、後方参照のために理論的にはより強力ですが、言語が補集合と共通部分の操作を簡単に表現できないため、実際には柔軟性が低くなります。

于 2010-10-20T16:13:36.207 に答える
9

正規表現を実行して、出力を論理的に反転するだけです。だから変更:

if(/foo/)

に:

if(!/foo/)

文字クラスは、先頭のカラットで反転できます。

[AZ]-> [^ AZ]

指定子を大文字にすると、多くの特殊文字にも逆文字があります。

\s whitespace
\S non-whitespace
\w word character
\W non-word-character
\d digit
\D non-digit
于 2010-10-20T11:57:20.360 に答える
6

考慮すべきいくつかのバリエーション:

特定の文字セットで構成される文字列に一致します。^[a-z]*$

特定の文字セット以外で構成される文字列に一致します。^[^a-z]*$

いくつかのショートカットがあることに注意してください。

  • \w:任意の英数字(を含む_)、
  • \W:英数字以外の文字。
  • \s:任意の空白文字、
  • \S:空白以外の文字、
  • \d:任意の桁、
  • \D:数字以外。

これは非常に複雑になる可能性があります。たとえば、必要な場合は...

  • 非文字のみ:[\d_\W]、または
  • 文字のみ:([^\d_\W]つまり、「数字でも、_でも、英数字でもない)

サブストリングを含むストリングに一致します。^.*substring.*$

サブストリングを含まないストリングに一致します。^(?:(?!substring).)*$

文字列内の各位置で、部分文字列の「存在しない」を確認する方法に注意してください。substring特定のサブ正規表現を含む、または含まない文字列に一致するように、任意の正規表現を置き換えることもできます。


何にでも一致:(.*改行も一致させたい場合はre.DOTALL、Pythonなどでプログラミング言語の対応するオプションを設定する必要があります)

そのオプションを設定する方法がわからない場合は、何にでも一致します。[\s\S]*

(何らかの理由で)何にも一致しない:

  • $^(つまり、文字列の開始前に文字列の終了を一致させます)、
  • \b\B(同時に単語の境界があり、単語の境界がない位置に一致する)または
  • (?!)(空の文字列と一致することが不可能な位置と一致します)。
于 2010-10-20T12:42:55.740 に答える
4

ネガティブ先読みを使用することにより、基本的なケースのほとんどを処理できるようになります

/(?!(OriginalRegex)).*?/
于 2010-10-20T12:25:53.607 に答える
3

最初の例は意味がありませんが、2番目の例ではクラス文字の否定を使用できます。

[a-z] --> [^a-z]
于 2010-10-20T11:54:31.580 に答える
1

正規表現の逆の定義を理解しようとしています。

match(input、regular_expression)= {match1、match2、...、matchN}

逆はどのように機能しますか?それは次のようなものである必要があります

match(input、inverse_regular_expression)= {imatch1、imatch2、...、imatchN}

もしそうなら、結果の最初のセットと2番目のセットの間の関係は何ですか?そうでない場合、それは何ですか?

于 2010-10-20T12:17:16.130 に答える