クイックスタート
チュートリアル
ツールと言語
リファレンス
書評
正規表現チュートリアル
はじめに
目次
特殊文字
非印刷文字
正規表現エンジンの内部動作
文字クラス
文字クラスの減算
文字クラスの積集合
簡略文字クラス
ドット
アンカー
単語境界
オルタネーション
オプション項目
繰り返し
グループ化とキャプチャ
バックリファレンス
バックリファレンス、パート2
名前付きグループ
相対バックリファレンス
ブランチリセットグループ
フリースペースとコメント
Unicode
モード修飾子
アトミックグループ
所有格量子化子
先行アサーションと後行アサーション
ルックアラウンド、パート2
マッチからテキストを除外する
条件式
バランスグループ
再帰
サブルーチン
無限再帰
再帰と量子化子
再帰とキャプチャ
再帰とバックリファレンス
再帰とバックトラッキング
POSIXブラケット式
ゼロ長のマッチ
マッチの継続
このサイトについて、さらに
はじめに
正規表現クイックスタート
正規表現チュートリアル
置換文字列チュートリアル
アプリケーションと言語
正規表現の例
正規表現リファレンス
置換文字列リファレンス
書評
印刷可能なPDF
このサイトについて
RSSフィードとブログ
RegexBuddy—Better than a regular expression tutorial!

ドットは(ほぼ)任意の文字にマッチします

正規表現において、ドットまたはピリオドは最も一般的に使用されるメタ文字の1つです。残念ながら、それはまた、最も一般的に誤用されるメタ文字でもあります。

ドットは、その文字が何であっても、単一の文字にマッチします。唯一の例外は改行文字です。このチュートリアルで説明されているすべての正規表現フレーバーでは、デフォルトではドットは改行文字にマッチしません。

この例外は、主に歴史的な理由から存在します。正規表現を使用する最初のツールは、行ベースでした。ファイルを行単位で読み取り、各行に正規表現を個別に適用していました。これらのツールでは、文字列に改行文字が含まれることは決してないため、ドットが改行文字にマッチすることは決してありませんでした。

最新のツールと言語は、非常に大きな文字列、あるいはファイル全体に正規表現を適用できます。VBScriptを除いて、ここで説明されている正規表現フレーバーにはすべて、改行文字を含むすべての文字にドットをマッチさせるオプションがあります。JavaScriptの古い実装にもそのオプションはありませんでした。正式にはECMAScript 2018仕様で追加されました。

PowerGREPでは、「ドットが改行文字にマッチする」というチェックボックスをオンにして、すべての文字にドットをマッチさせます。EditPad Proでは、「ドット」または「ドットが改行文字にマッチする」検索オプションをオンにします。

Perlでは、ドットが改行文字にもマッチするモードを「シングルラインモード」と呼びます。これは少し残念です。この用語を「マルチラインモード」と混同しやすいからです。マルチラインモードはアンカーのみに影響し、シングルラインモードはドットのみに影響します。正規表現コードの後に「s」を追加することで、シングルラインモードを有効にできます。以下のようにm/^regex$/s;.

他の言語と正規表現ライブラリは、Perlの用語を採用しています。.NETのRegexクラスを使用する場合は、以下を指定してこのモードを有効にします。RegexOptions.Singleline例:Regex.Match("string", "regex", RegexOptions.Singleline).

JavaScript(古いブラウザとの互換性のため)とVBScriptでは、以下のような文字クラスを使用できます。[\s\S]任意の文字にマッチします。この文字クラスは、空白文字(改行文字を含む)か、空白文字ではない文字のいずれかである文字にマッチします。すべての文字は空白文字か非空白文字のいずれかなので、この文字クラスは任意の文字にマッチします。以下のようなオルタネーションを使用しないでください。(\s|\S)これは遅いです。そして、絶対に以下を使用しないでください。(.|\s)これは、スペースとタブが両方によってマッチされる可能性があるため、壊滅的なバックトラッキングにつながる可能性があります。.そして\s.

Boostのすべての正規表現文法では、ドットはデフォルトで改行文字にマッチします。BoostのECMAScript文法では、以下を使用してこれをオフにすることができます。regex_constants::no_mod_m.

改行文字

ドットのサポートは正規表現フレーバー間で普遍的ですが、改行文字として扱う文字には大きな違いがあります。すべてのフレーバーは改行\nを改行文字として扱います。UNIXテキストファイルは、単一の改行で行を終了します。このチュートリアルで説明されているすべてのスクリプト言語は、他の文字を改行文字として扱いません。テキストファイルは通常、\r\nのペアで改行されるWindowsでも、これは問題ではありません。これらのスクリプト言語は、デフォルトでファイルを読み書きする際にテキストモードを使用するためです。Windowsで実行する場合、\r\nペアは自動的に\nに変換され、ファイルに書き込まれる\nは自動的に\r\n.

として書き込まれます。std::regexXMLスキーマXPathもキャリッジリターン\rを改行文字として扱います。JavaScriptは、Unicodeの改行セパレータ\u2028と段落セパレータ\u2029を追加します。Javaにはこれらに加えて、Latin-1の改行制御文字\u0085が含まれています。Boostは、改行文字のリストにフォームフィード\fを追加します。DelphiJGsoftフレーバーだけがすべてのUnicode改行をサポートし、垂直タブで組み合わせを完成させます。

.NETは、\n以外の文字を改行文字として扱うフレーバーのリストには含まれていません。UNIXを起源とするスクリプト言語とは異なり、.NETはWindows開発フレームワークであり、読み取るテキストファイルからキャリッジリターン文字を自動的に削除しません。Windowsテキストファイルを文字列全体として読み込むと、キャリッジリターンが含まれます。正規表現abc.*をその文字列で使用すると、RegexOptions.SingleLineを設定しない場合、abcと、同じ行の後に続くすべての文字、そして行末のキャリッジリターンにマッチしますが、その後の改行文字にはマッチしません。

一部のフレーバーでは、改行文字として扱う文字を制御できます。JavaにはUNIX_LINESオプションがあり、\nのみを改行文字として扱います。PCREには、\nのみ、\rのみ、\r\n、またはすべてのUnicode改行文字を選択できるオプションがあります。

POSIXシステムでは、POSIXロケールによって改行文字が決定されます。Cロケールは、改行\nのみを改行文字として扱います。UnicodeロケールはすべてのUnicode改行をサポートします。

\Nは改行文字に決してマッチしません

Perl 5.12とPCRE 8.10では、\Nが導入されました。これは、ドットと同様に、改行文字ではない任意の単一文字にマッチします。ドットとは異なり、\Nは「シングルラインモード」の影響を受けません。(?s)\N.はシングルラインモードをオンにし、その後、改行文字ではない任意の文字に続いて、改行文字であるかどうかに関係なく任意の文字にマッチします。

改行文字として扱う文字を制御するPCREのオプションは、\Nに全く同じように影響します。

PHP 5.3.4とR 2.14.0も、正規表現のサポートがPCRE 8.10以降に基づいているため、\Nをサポートしています。JGsoft V2も\N.

をサポートしています。

ドットを控えめに使用する

ドットは非常に強力な正規表現メタ文字です。怠惰になることができます。ドットを入れると、有効なデータで正規表現をテストすると、すべてがうまくマッチします。問題は、正規表現がマッチすべきではない場合にもマッチすることです。正規表現初心者にとって、これらの場合のいくつかは最初はそれほど明白ではないかもしれません。簡単な例で説明しましょう。mm/dd/yy形式の日付にマッチしたいが、日付区切り文字の選択はユーザーに任せたいとします。簡単な解決策は\d\d.\d\d.\d\d02/12/03です。最初はうまくいくように見えます。日付02512703のようにうまくマッチします。問題は5もこの正規表現によって有効な日付と見なされることです。このマッチでは、最初のドットは7にマッチし、2番目のドットは

にマッチします。明らかに意図したものではありません。\d\d[- /.]\d\d[- /.]\d\d

の方が良い解決策です。この正規表現では、ハイフン、スペース、ドット、スラッシュを日付区切り文字として使用できます。ドットは文字クラス内ではメタ文字ではないため、バックスラッシュでエスケープする必要がないことに注意してください。99/99/99この正規表現はまだ完璧にはほど遠いものです。これは[01]\d[- /.][0-3]\d[- /.]\d\dは一歩進んだ表現ですが、それでもマッチします。19/39/99正規表現をどの程度正確にしたいかは、その用途によって異なります。ユーザー入力の検証を行う場合は、完璧でなければなりません。一方、常に同じ方法でファイルを生成する既知のソースからのデータファイルを解析する場合は、最後の試行で十分にエラーなくデータの解析を行うことができるでしょう。例題セクションで日付にマッチするより優れた正規表現を見つけることができます。

ドットの代わりに否定文字クラスを使用する

否定文字クラスは、多くの場合、ドットよりも適切です。繰り返し演算子アスタリスクとプラス記号を説明するチュートリアルセクションでは、この点がより詳細に説明されています。しかし、この警告はここで言及するほど重要です。再び例を使って説明しましょう。

ダブルクォートで囲まれた文字列にマッチさせたいとしましょう。簡単そうに聞こえます。ダブルクォートの間に任意の数の任意の文字を含めることができるため、".*"これでうまくいくように見えます。ドットは任意の文字にマッチし、アスタリスクはドットを0回以上繰り返すことを許可します。この正規表現をダブルクォートで「文字列」を囲むでテストすると、「文字列」にうまくマッチします。それでは、次をテストしてみましょう。ヒューストン、"文字列1"と"文字列2"に問題があります。"応答してください。

痛いです。正規表現は"文字列1"と"文字列2"にマッチします。明らかに意図したものではありません。アスタリスクgreedy(貪欲)であることがその理由です。

日付マッチングの例では、ドットを文字クラスに置き換えることで正規表現を改良しました。ここでは、否定文字クラスを使用して同じことを行います。ダブルクォートで囲まれた文字列の元の定義は間違っていました。クォートの間に任意の文字を任意の数だけ含めたいわけではありません。クォートの間には、ダブルクォートや改行文字ではない任意の数の文字を含めたいのです。そのため、適切な正規表現は"[^"\r\n]*"です。使用しているフレーバーが短縮記法\vをサポートして改行文字にマッチさせることができる場合は、"[^"\v]*"はさらに優れたソリューションです。