私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?

私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?

私はいくつかのプログラム(grep、sed、awk、perl、python、ruby、ksh、bash、zsh、find、emacs、vi、vim、gedit、...)でうまく動作する正規表現を書いています。ただし、他のプログラム(または別のUNIXバリアント)で使用すると、一致は停止します。なぜ?

答え1

残念ながら、歴史的な理由により、ツールごとに正規表現の構文が若干異なり、時には一部の実装には他のツールがサポートしていない拡張機能が含まれています。共通点がありますが、各ツールの作成者が異なる選択をしたようです。

その結果、正規表現があるツールで動作する場合は、他のツールでも動作するように変更する必要があります。一般的に使用されるツールの主な違いは次のとおりです。

  • 演算子に+?|(){}バックスラッシュが必要かどうか。
  • .[]*^$基本的な機能に加えて、一般的にどの拡張がサポートされていますか?+?|()

この答えに私はリストしました主な基準。詳細については、使用しているツールのマニュアルを確認してください。

ウィキペディア正規表現エンジンの比較一般的な実装でサポートされている機能をリストした表があります。

基本正規表現(着替え)

デフォルトの正規表現は次のように与えられます。POSIX規格。使用される構文は次のとおりです。grepsedそしてvi。この構文は次の機能を提供します。

  • ^そして$行の始まりと終わりでのみ一致します。
  • .すべての文字(または改行を除くすべての文字)と一致します。
  • […]括弧内にリストされている文字(文字セット)の1つと一致します。開いている括弧の後の最初の文字がある場合は、リストにない^文字が一致します。を含めるには、]開始の直後に配置します[[^負のセットの場合は後で配置します)。-2 つの文字の間に範囲を表す場合、リテラルを含めるには、-範囲として解析できない場所に配置します。
  • ^$.*\[次の文字の前にあるバックスラッシュです。
  • *先頭の文字またはサブ式を0、1、またはそれ以上一致します。
  • \(…\)*演算子または逆参照と置換で使用される構文グループ\DIGIT
  • 逆参照\1、、、\2...は、対応するグループに一致する正確なテキストと一致します(たとえば、一致が一致しませ\(fo*\)\(ba*\)\1foobaafoofoobaafo。 10番目以降のグループを参照する標準的な方法はありません(標準的な意味は\10次の最初のグループです0)。

以下の機能も標準ですが、一部の制限された実装ではありません。

  • \{m,n\}前の文字またはサブ式と一致します。到着N移流;Nまたは省略可能で正確\{m\}
  • かっこ内では、キャラクタークラス[[:alpha:]]たとえば、任意の文字と一致させるために使用できます。現代的な実装角かっこ表現)また含まれています要素の構成like[.ll.]と同等のクラス[=a=]

次の拡張は一般的ですが、特にGNUツールでは、すべての実装で見つからない可能性があります。使用しているツールのマニュアルを確認してください。

  • \|代替:foo\|bar一致fooまたはbar
  • \?(略語\{0,1\})と\+(略語\{1,\})は、それぞれ最大1回または最低1回先行文字またはサブ式と一致します。
  • \n改行、\tタブの一致などを一致させます。
  • \wすべての単語コンポーネント(省略されたがローカライズされ[_[:alnum:]]たバリエーションを含む)と一致し、\W単語コンポーネントではないすべての文字と一致します。
  • \<そして、\>それぞれの単語の先頭または末尾でのみ空の文字列と一致します。\b一致または一致しない場合と\B一致します。\b

演算子のないツールには\|正規表現の完全な機能はありません。逆参照を使用すると、数学的意味で正規表現が実行できないいくつかの追加操作を実行できます。

拡張正規表現(むしろ)

拡張正規表現は次のように与えられます。POSIX規格。 BREと比較して最大の利点は規則性です。すべての標準演算子は純粋な句読点であり、句読点の前のバックスラッシュは常にこれを引用します。使用される構文は次のとおりです。awkgrep -Eまたはegrep、BSD(およびGNUとまもなくPOSIX)sed -E(以前sed -rはGNU sed)とbash/ksh93/yash/zsh=~オペレーター。この構文は次の機能を提供します。

  • ^そして$行の始まりと終わりでのみ一致します。
  • .すべての文字(または改行を除くすべての文字)と一致します。
  • […]括弧内にリストされている文字(文字セット)の1つと一致します。イニシャル^と範囲の完成はBREと同様に機能します(上記を参照)。キャラクタークラス使用できますが、一部の実装ではありません。最新の実装では、同等のクラスと照合順序要素もサポートしています。一部の実装では、括弧内のバックスラッシュは次の文字を表します。\\バックスラッシュは移植性を示すために使用されます。
  • (…)*はor\DIGITの代わりに使用される構文グループです。
  • |代替:foo|bar一致fooまたはbar
  • *、先行文字またはサブ式を複数回一致します(0回以上+、1回以上、0回または1回)。?*+?
  • 次の文字が英数字でない場合は、バックスラッシュで囲みます。
  • {m,n}前の文字またはサブ式と一致します。そしてN時間(一部の実装ではありません)Nまたは省略可能で正確{m}
  • BREのいくつかの一般的な拡張:逆参照(特にビジーボックスの実装で使用されている場合を除いてawkにはありません)、単語境界、単語コンポーネントなど\DIGIT$0 ~ "(...)\\1"\n\t\b\B\b\B

PCRE(Perl互換正規表現)

PCREは、もともとEREによって開発されたEREの拡張です。真珠GNUによって採用grep -Pそしてさまざまな最新のツールとプログラミング言語、一般的に、ポリメラーゼ連鎖反応図書館。よりPerlドキュメント例を含む良い形式です。 PCREは、最新のPerlバージョンのすべての機能をサポートしていません。たとえば、PerlだけがPerlコードの実行をサポートしています。よりPCREパンフレットサポートされている機能の概要を確認してください。 EREに新しく追加された主な事項は次のとおりです。

  • (?:…)非キャプチャグループです。に似ています(…)が、逆参照を計算しません。
  • (?=FOO)BAR(Lookahead)matchがBAR同じ場所から始まる一致もある場合にのみ適用されますFOO。これは、一致に次のテキストを含めずに一致を固定するのに最も便利です。foo(?=bar)一致fooが後ろにある場合にのみ適用されますbar
  • (?!FOO)BAR(否定的な予測)一致するがBAR同じ場所に一致するものはありません。FOO例えば;で始まらない小文字の単語を(?!foo)[a-z]+一致させますfoo[a-z]+(?![0-9)後に数字のない小文字の単語と一致します(したがって、foo123一致foするものではありませんfoo)。
  • (?<=FOO)BAR(lookbehind)はmatchと一致しますBARが、matchが直前にある場合にのみ適用されますFOOFOO既知の長さが必要です(たとえば、反復演算子は使用できません*)。これは、一致に前のテキストを含めずに一致を(?<=^| )foo固定するのに役立ちます。fooただし、前にスペースがある場合、または文字列の先頭にある場合にのみ可能です。
  • (?<!FOO)BAR(否定的な振り返り)はmatchと一致しますBARが、matchが直前にない場合にのみ適用されますFOOFOO既知の長さが必要です(たとえば、反復演算子は使用できません*)。これは、一致に前のテキストを含めずに一致を固定するのに役立ちます。(?<![a-z])foomatchfooただし、前に小文字がない場合にのみ該当します。

Emacs

Emacsの構文BREとEREの間。 Emacsを除いて、これは-regexGNU検索の基本的な構文です。 Emacsは次の演算子を提供します:

  • ^, $, ., […], *, +, ?EREに示すように
  • \(…\)、、、、\|BRE\{…\}に示すように\DIGIT
  • 追加のバックスラッシュ文字シーケンス;\<\>単語の境界、およびEmacsに似た構文を使用する他のエンジンでは、しばしばサポートされていない最新バージョンのEmacsのより多くの機能があります。

シェル

シェルグローブ(ワイルドカード)は、正規表現とはまったく異なり、あまり強力な構文を使用してパターンマッチングを実行します。シェルに加えて、これらのワイルドカードはfind -namersyncフィルタなどの他のツールで使用できます。POSIXモード以下の機能が含まれています。

  • ?単一文字と一致します。
  • […]一般的な正規表現構文の文字セットです。一部のシェルは文字クラスをサポートしていません。一部のシェルでは、これを否定するのではなく、!この^コレクションが必要です。
  • *すべての文字シーケンスと一致します(/通常はファイルパスと一致する/場合は除外***/
  • バックスラッシュは次の文字を引用します。

Ksh提案追加機能これは、正規表現のすべての機能に一致するパターンを提供します。これらの機能はbashで実行した後でも使用できますshopt -s extglob。 Zshには1つありますその他の構文ただし、ksh以降の構文もサポートできますsetopt ksh_glob


1rematchpcreこのオプションを有効にしzshないと、=~PCREが使用されます。 ksh93の拡張正規表現は、ツアー演算子など、一部のPerl拡張演算子もサポートしています。

関連情報