なぜいくつかの正規表現コマンドは、さまざまな文字を含む '\'の反対の解釈を持っているのですか?


10

たとえば、次のコマンドを見てください。

find . -regex ".*\.\(cpp\|h\)"

これにより、ディレクトリ内のすべての.hおよび.cppファイルが検索されます。ピリオド文字「。」正規表現では通常、「任意の文字」を意味します。実際のピリオドのみに一致させるには、バックスラッシュ文字「\」を使用してエスケープする必要があります。

この場合、特別な意味を持つ文字を指定すると、それをエスケープして、その文字が表す実際の文字を取得する必要があります。

ここで、括弧と「or」バーをそれぞれ「(」、「)」、「|」の文字として扱います。これらには、正規表現のグループ化に使用される特別な意味もあります。ただし、特別な意味を得るには、バックスラッシュを使用して文字をエスケープする必要があります。バックスラッシュがなければ、文字はそれが表す実際の文字の意味を持ちます。

なぜ「。」「(」、「)」、および「|」とは異なる方法で処理されますか?

回答:


12

答えは本当に「ただ」です。さまざまな正規表現構文がたくさんあり、それらは同じような外観を共有し、通常は基本は同じですが、詳細は異なります。

歴史的に、すべてのツールには独自の新しい実装があり、作者が最善と考えたことは何でも行っていました。エスケープの有無にかかわらず文字を特殊なものにすることにはバランスがあります。「自然に特殊な」文字が多すぎると、一致させるために常にエスケープする必要があります。または、逆に、()グループ化などの一般的な正規表現構文を使用するには、大量のエスケープが必要になります。そして、プログラムを作成するすべての人が、プログラムのマッチングのニーズ、正しいアプローチであると感じたもの、および月の位相に基づいて、その方法を決定しました。

基本正規表現」と「拡張正規表現」を定義するPOSIXからの標準化の試みがあります。恐ろしいことに、これらは互いに逆方向に機能します\時には、完全な一貫性ではありません。

Perl正規表現は別の事実上の標準になりました。2つの理由があります。1つ目は非常に柔軟で強力であり、2つ目は「\は常に英数字以外の文字をエスケープする」などの規則で、実に正気です。

GNU Findには、-regextype使用する正規表現構文を変更できるオプションがあります。悲しいことに、「perl」はオプションではありません。少なくとも、私が持っているfindのバージョンでは。(当然のことながら、デフォルトはGNUの「emacs」であり、その構文はここに記載されています。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.