正規表現メモ

最終更新日 2019年1月1日

正規表現は使い慣れれば便利なものですが、ツールによって 使える正規表現演算子(メタキャラクタ)に違いがあったりして 戸惑うこともあります。そこで、正規表現を扱うツールの 代表的なものを幾つか選び、そこで使われている正規表現演算子 をまとめてみました。

お断り:
このページでは使い方の例であるとかサンプルなどは書いていません。


Table of contents

  1. grepで使用できる正規表現
  2. egrepで使用できる正規表現 (obsolete)
  3. sedで使用できる正規表現
  4. awkで使用できる正規表現
  5. Perlで使用できる正規表現 (ver 5.20.1)
  6. Pythonで使用できる正規表現 (ver 3.4)
  7. Rubyで使用できる正規表現 (ver 2.4.1)
  8. gawk (3.0以降)で使用できる正規表現
  9. Tcl 8.2.3(以降)で使用できる正規表現
  10. PCREで使用できる正規表現 ()
  11. PHPで使用できる正規表現(mb_ereg)
  12. PHPで使用できる正規表現
  13. .NET Frameworkで使用できる正規表現
  14. Java(1.4以降)で使用できる正規表現
  15. POSIX 1003.2での正規表現について
  16. 各正規表現演算子の説明
  17. 各エスケープシーケンスの説明
  18. ある文字列を含まない正規表現
  19. その他

各種ユーティリティで使える正規表現

grepで使用できる正規表現演算子

GNU grepは、デフォルトではPOSIX 1003.2で規定されている Basic Regular Expressionと、 それに加えてGNU grepで拡張されているいくつかの正規表現演算子が使えます。 これらのうち、\+、\?、\|、\w、\W、\<、\>、\b、\B がGNU grepにおける拡張であり、 POSIXの規定にはありません(時折GNU 拡張も含めたものをBREだと書かれたものを見かけますが)。 また、他の古い処理系などでは[:alnum:] などの表記が使えないかもしれません。また、GNU grep 2.5以降では PCREのリンクを有効にしてビルドした場合に PCREを使ったPerl互換の正規表現指定ができます PCREによって使うことのできる正規表現については PCREで使える正規表現または PCRE man pageを参照してください。 grepで使用されるモードはMULTILINEモードです。

POSIXのgrepでは、-Eオプションと共に起動した場合には 正規表現としてExtended Regular Expressionを受付ける ようになります。この場合使用できる演算子には

といったものがあります。POSIX 1003.2では EREで 後方参照が使えるとは定義されていませんが、 GNU grep は使用可能です。

egrepで使用できる正規表現演算子

GNU grep を egrepという名前で起動したときに使用できる正規表現演算子は以下のものです。 grepに-Eオプションを指定したときと似ていますが、全く同一というわけではありません。 また、通常egrepという名前が付けられているものに比べ、 使用できる演算子が増えているので注意が必要です。
2003年2月21日付記: GNU grep 2.5では-Eオプション指定時とegrepで起動した ときの挙動は同一です。-Eオプション指定時の動作については 前の項を参照してください(2.4あたりでこうなったようです)。

「コマンド名」による動作の違いはもう書くまでもないことかと思いますので いずれ削除します。

sedで使用できる正規表現演算子

POSIX 1003.2で規定されているsedでは、以下の演算子が使用できます。

GNU sedでは上記のものに加えて、以下のものが使えます。

付記: GNU sed 4.0.5以降ではオプション指定によりEREを使えるようになります(使えるEREはGNU のegrepと同じ)。

'-E'
'-r'
'--regexp-extended'
     Use extended regular expressions rather than basic regular
     expressions.  Extended regexps are those that 'egrep' accepts; they
     can be clearer because they usually have fewer backslashes.
     Historically this was a GNU extension, but the '-E' extension has
     since been added to the POSIX standard
     (http://austingroupbugs.net/view.php?id=528), so use '-E' for
     portability.  GNU sed has accepted '-E' as an undocumented option
     for years, and *BSD seds have accepted '-E' for years as well, but
     scripts that use '-E' might not port to other older systems.  *Note
     Extended regular expressions: ERE syntax.

GNU sed 4.1.2 では正規表現演算子として\s\Sが使えるようになっています。

undocumented な機能ですが、 GNU sed 4.1.2 以降ではオプション指定によりPerl5互換の正規表現を使えるようになります(有効にしてコンパイルした場合)。 ソースコードに以下のような部分があります。

#ifdef REG_PERL
#define PERL_HELP _("  -R, --regexp-perl" \
                    "\n                 use Perl 5's regular expressions" \
                    " syntax in the script.\n")
#endif

awkで使用できる正規表現演算子

awkでの注意事項
処理系によっては、/[/]/のように、文字クラス指定中に/を置くと エラーとなる場合があります。これはそういった文字クラスの中に置かれた /を、正規表現をくくる/と取り違えるのが原因です。このばあい、/を\ を使ってエスケープする必要があります。

補足: gawk 3.0.x 以降では、扱える正規表現が拡張されました。 詳しくはgawk 3.0以降で使用できる正規表現演算子を 参照してください。

mawk

Perlで使用できる正規表現演算子

2017年12月31日時点の最新バージョン 5.26.1
2019年5月1日時点の最新バージョン 5.28.2

簡単なリファレンスが perlreref perlreref - Perl の正規表現のリファレンス にあります。また チュートリアル perlretut - Perl の正規表現のチュートリアル があります。

特記事項 → Perlに関する特記事項

以下はPerl5.6で追加されたものです。詳しくは Perl5.6のドキュメント もしくは それ以降のバージョンのドキュメント perlre - Perl 正規表現 - perldoc.jp を参照してください。

\pは後続する名前のクラス(プロパティ、スクリプト、ブロック)に属する文字にマッチし、 \Pは後続する名前のクラスに属さない文字にマッチします。クラスの名前が一文字のときは ブレースを省略できます。クラス名に"^"を前置することにより否定形の 指定を行うことも可能です。

Perl5.8以降では(5.6でも使えたようです)\pや¥Pで始まるプロパティ指定は 標準Unicode属性も可能です。詳しくは perlunicode perlunicode - Perl における Unicode サポート を参照してください。日本語による説明が Unicodestandard にもあります。

Perl 5.8以降ではユーザーが任意のプロパティを作成することができます (IsまたはInを必ず前置)。詳しくは perlunicode perlunicode - ユーザ定義文字特性 を参照してください。一例をあげると

    sub InKana {
        return <<END;
    3040\t309F
    30A0\t30FF
    END
    }

というサブルーチンを定義することによって、ひらがなもしくはカタカナにマッチする プロパティInKanaを使用することが可能になります。perl 5.8.5ではこのサブルーチン 定義において intersection機能を使うことが可能となりました。詳しくは perlunicode585 perlunicode - ユーザ定義文字特性 を 参照してください。

Perl 5.10.0 での追加。

Perl 5.26.0 時点でのまとめ (あとで書く)

Perl 5.28.0 時点でのまとめ (あとで書く)

Perl 5.30.0 時点でのまとめ Perl v5.30 lets you match more with the general quantifier | The Effective Perler

Things to Remember
    The general quantifier {,} has a maximum number of repetitions, even though that is probably more than you ever need.
    The + should be equivalent, but can match much more.
    v5.30 will increase the limit for {,}. If you've been working around that limitation, I want to hear about what you are doing. 
  

Perl 6で使用できる正規表現演算子

perl 6 の Rules について (あとで書く)

Pythonで使用できる正規表現演算子

本稿修正時のPyhtonのバージョン 3.6.4
6.2. re — Regular expression operations — Python 3.6.4 documentation

正規表現コンパイル時に指定できるオプションもあります。 Python 2.4 から以下のものが使えるようです。 Perlとは異なり conditionの 部分には名前つきパターンのグループ名も可能なようですが、 先読み戻り読み等の指定はできないようです。

2.4以降で追加/変更されたあれこれ

(?(id/name)yes-pattern|no-pattern)

Will try to match with yes-pattern if the group with given id or name exists, and with no-pattern if it doesn’t. no-pattern is optional and can be omitted. For example, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) is a poor email matching pattern, which will match with '<user@host.com>' as well as 'user@host.com', but not with '<user@host.com'.

New in version 2.4.

Changed in version 3.3: The '\u' and '\U' escape sequences have been added.

Changed in version 3.6: Unknown escapes consisting of '\' and an ASCII letter now are errors.
Changed in version 3.5: Added support for group references of fixed length.

New in 3.6

(?imsx-imsx:...)

(Zero or more letters from the set 'i', 'm', 's', 'x', optionally followed by '-' followed by one or more letters from the same set.) The letters set or removes the corresponding flags: re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose), for the part of the expression. (The flags are described in Module Contents.)

New in version 3.6.

Ruby で使用できる正規表現演算子

本稿修正時のRubyのバージョン 2.4.1 (1.9以前の記述は削除しました)

詳しいドキュメントは 正規表現 (Ruby 2.4.0) にあります。

Ruby 2.0.0 より正規表現ライブラリは、それまで使っていた鬼車からその派生の鬼雲 (Onigmo/README.ja at master · k-takata/Onigmo) に変更されました。

Unicode プロパティ 使用できるプロパティなどは Onigmo/UnicodeProps.txt at master · k-takata/Onigmo

部分式呼び出し 詳しくは 正規表現 (Ruby 2.4.0)

Ruby 2.4.1 で 非包含オペレーターが追加されました。

gawk (3.0以降)で使用できる正規表現演算子

特記事項:
gawk 3.0.0以降、それまでのバージョンのものとは異なり "." が 改行にもマッチするように仕様が変更されました。 gawk 3.0に関しては http://www.kt.rim.or.jp/~kbk/gawk-30/index.html にマニュアルの邦訳があります(4以降のドキュメントを訳す元気はない)。

2017年12月追記: gawk で 4.0 へのバージョンアップ時に以下の変更あり。

Changes from 3.1.8 to 4.0.0
---------------------------
1. The special files /dev/pid, /dev/ppid, /dev/pgrpid and /dev/user are
   now completely gone. Use PROCINFO instead.

2. The POSIX 2008 behavior for `sub' and `gsub' are now the default.
   THIS CHANGES BEHAVIOR!!!!

3. The \s and \S escape sequences are now recognized in regular expressions.

Tcl 8.2.3(以降)で使用できる正規表現演算子

8.1になってPerl5ライクな正規表現が使えるようになっています。

メタ構文。 (?bc)regexp のように使います。複数同時に指定することが可能です。

正規表現が以下のシーケンスで始まっていた場合、解釈に違いが出ます。

詳しくは re_syntax をどうぞ。 日本語のドキュメントが Tcl 8.4.1 マニュアル ビルトインコマンドリファレンス re_syntax にあります。

PCRE(ver 4.x)で使用できる正規表現演算子

PCRE - Perl Compatible Regular Expressions はPerl 5.8にほぼ準じた正規表現が使えます。いろいろな処理系でライブラリとして使われています。

PCRE の2017年12月時点でのバージョンについて

There are two major versions of the PCRE library. The newest version, PCRE2, was released in 2015 and is at version 10.30.

The original, very widely deployed PCRE library, originally released in 1997, is at version 8.41, and the API and feature set are stable—future releases will be for bugfixes only. Any new features will be added to PCRE2, and not to the PCRE 8.x series.

PCREのPOSIXキャラクタクラス指定では"^"を前置した否定形も 使用することができます(ex: [^:digit:])。

PCRE 5.0ではUnicodeプロパティが使えます(有効にしてコンパイルした場合)。 その場合に使用できるプロパティは以下の表の通りです。使用する場合、 \p{Ll}、\P{Lu}のようにします(\pは指定するプロパティに含まれるキャラクタ、 \Pは指定するプロパティに含まれないキャラクタにマッチします)。 Perlと同様、\p{^Lu}のような否定形の指定も可能です。 \p,\Pに続く プロパティ指定が一文字である場合、ブレースは省略可能です。また、\Xという エスケープシーケンスも使えます。これは (?>\PM\pM*) と等価です(アクセント つきの文字などの指定です)。

PCRE 5.0で使えるUnicodeプロパティ
表記 意味
C Other
Cc Control
Cf Format
Cn Unassigned
Co Private use
Cs Surrogate
L 文字
Ll 小文字
Lm Modifier letter
Lo Other letter
Lt Title case letter
Lu 大文字
M Mark
Mc Spacing mark
Me Enclosing mark
Mn Non-spacing mark
N 数字
Nd 十進数字
Nl Letter number
No Other number
P Punctuation
Pc Connector punctuation
Pd Dash punctuation
Pe Close punctuation
Pf Final punctuation
Pi Initial punctuation
Po Other punctuation
Ps Open punctuation
S Symbol
Sc Currency symbol
Sk Modifier symbol
Sm Mathematical symbol
So Other symbol
Z Separator
Zl Line separator
Zp Paragraph separator
Zs Space separator

お断り:
PCREは、2007年10月10日時点で7.2までバージョンが上がっています。 色々追加されているものもあるのでこの情報は古いです。

PHP で使用できる正規表現演算子

POSIX regex (ereg_* で使える正規表現)は deprecated となっています。 mb_ereg の扱いがどうなっているのかはよくわかりません (deprecated ではないようですが)。 マルチバイト対応PHPには三種類の正規表現ルーチンがありますが、 ここではマルチバイト文字対応のmb_eregにしぼって列挙します。 Rubyの正規表現ルーチンを使っているので、Rubyのものと基本的には同じです。 preg_*関数群はPCREを使っているので使える正規表現はPCRE に準じます。ereg_*で使える正規表現はPOSIX ERE[[:<:]][[:>:]] のようです(Henry Spencer作のライブラリらしい)。

The POSIX functions are deprecated. Instead of the "ereg" collection you want to use something from the PCRE world. http://www.php.net/manual/en/book.pcre.php

PHP本体のバージョンと使用しているPCREのバージョンとの対応は PHP: インストール手順 - Manual の「バンドルされている PCRE ライブラリの更新履歴」を参照のこと。

.NET Frameworkで使用できる正規表現

たぶん 2.0辺りのもの。 そこから2017年12月31日現在の最新(4.7.1)までに 追加・変更がどの程度あったのかは未調査。

特記事項 → NETの正規表現に関する特記事項

コンパイル時に指定できるオプションもあります。 詳しくは .NET Framework の正規表現を参照してください。

Java(1.4以降)で使用できる正規表現

特記事項 → Javaの正規表現に関する特記事項

コンパイル時に指定できるオプションもあります。 詳しくはPattern (Java2 プラットフォーム SE v1.4.0 を参照してください。


POSIX 1003.2

POSIX 1003.2での正規表現について

POSIX 1003.2では、二種類の正規表現 Basic Regular Expression (以下BRE)と Extended Reuglar Exression(以下ERE)が定められています。 BREを使用するユーティリティには、ed, ex, vi, more, sed, grepなど、 EREを使用するユーティリティには awk, egrep があります。 Regular ExpressoionsPOSIX 1003.2 regular expressionsに説明があります。

BRE で使える正規表現演算子(メタキャラクタ)は以下の通りです。

EREで使える正規表現演算子(メタキャラクタ)は以下の通りです。


正規表現演算子

各正規表現演算子の説明

.

任意のキャラクタ一文字とマッチします。処理系やオプション指定によって、 これが改行にマッチするものとしないものがあります。POSIX 1003.2では改行にも マッチするように規定されているようです。

幾つかの処理系でのオプション指定をまとめました →

*

演算子の直前に置かれている部分正規表現の可能な限り大きい繰り返しに マッチします。繰り返しの回数は0回でもかまいません。例を挙げると、

  fo*

は、foにもfooにもマッチしますし、f(oが一個もない)にもマッチします。 一般的には

  (foo)*

のように繰り返しの対象となるものは部分正規表現でも受け付けられますが、 処理系によっては文字の繰り返ししか認めていないものもあります。

*?

*と同様ですが、マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります)に行われる点が 異なります。 (参照: “ものぐさなマッチングとは”)

+
\+

*と似ていますが、直前にある部分正規表現の一回以上の繰り返しにマッチします。 つまり、 wh+y という正規表現は、why や whhhyにはマッチしますが、*とは違って、 wyとはマッチしません。 \+は、GNU grepやGNU sedで用いられるこれと等価な演算子です。 これは他の処理系では使えないでしょう。

+?

+と同様ですが、 マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります)に行われる点が 異なります。 (参照: “ものぐさなマッチングとは”)

?
\?

直前にある部分正規表現、もしくは空文字列にマッチします。 \?は、GNU grepやGNU sedで用いられるこれと等価な演算子です。 これは他の処理系では使えないでしょう。

??

?と同様ですが、 マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります)に行われる点が 異なります。 (参照: “ものぐさなマッチングとは”)

|
\|

これら二つの演算子は、選択を行なうためのものです。演算子の 左右に置かれた部分正規表現のいずれかにマッチします。 ^X|0 は先頭にXがある文字列か、0を含む文字列にマッチします (^と|は両方とも正規表現演算子ですが、その優先順位は ^が上のため、このような解釈になります)。 \|は、GNU grepやGNU sedで用いられる等価な演算子です。 これは他の処理系では使えないでしょう。

[char-list]

[]の中に置かれた文字のいずれかにマッチします。 これはキャラクタクラスなどと呼ばれます。[ABC]という 指定は、A, B, Cのいずれかにマッチします。 連続したキャラクタ群を指定する場合、その群の先頭と終端を -で繋いだ形で指定することができます。たとえば、[ABCDEFG]は [A-G]と等価な指定です。 ここでの順序はlocaleによって定められた順序に従います。 あるlocaleでは[a-z]に大文字の大部分が含まれたりする場合があります。 たとえば GNU/Linux の en_US localeでは、
a A b B c C d D ... x X y Y z Z という並びになります。

[の直後に^がきていた場合 には意味が逆になり、指定したキャラクタ群の補集合、つまり []内に置かれた文字以外の文字に マッチするということになります。たとえば[^ABC]という 正規表現は A, B, C 以外のキャラクタにマッチします。 範囲指定の終端と始点を共有する[a-c-e]のような指定をしたときの 動作は未定義です。

キャラクタクラスの中では多くのメタキャラクタがその意味を失います。 特に、伝統的なegrepでは、[]の中では\によるエスケープも効きません (\自体もその特殊な意味を失ってしまう)。そういった場合に ]や^、-といった[]内で特殊な意味を持つキャラクタをクラスに 含めたいときには []^-]のように記述します。つまり、^は [の直後以外に、]は[の直後(補集合を指定しているときには^の 直後)に置き、-はリストの最後に置くというやり方を使います。

最近の処理系では\によるエスケープや\を使ったメタキャラクタ(\wや\sなど)が 有効なものが多いようです。逆に、鬼車などでは[や-、]をキャラクタクラスに 含めるときはそれらをエスケープすることが推奨されています。

鬼車(やSunのJavaの正規表現パッケージ)では、キャラクタクラスの集合演算が 可能です。詳しくは 鬼車 正規表現の 文字集合の項を参照してください。

よくある勘違い
[^foo]bar という正規表現は、「fooではない文字列に続いてbarという文字列が続くもの」 ではありません。「fでもoでもない文字に続いてbarという文字列が続いたもの」 です。[]で囲んだものが表しているのは 文字列ではなく文字の集合(その中に含まれる/含まれない文字のどれか) だということに注意してください。

よくある勘違い その2
前述した通り、 ブラケットに囲まれている中ではほとんどのメタキャラクタはその特殊な意味を失います。 したがって、 [^(foo)]bar という正規表現もまた、「fooではない文字列に続いてbarという文字列が続くもの」 ではありません。「fでもoでも(でも)でもない文字に続いて barという文字列が続いたもの」 です。 []の内側では、文字列や(より小さな)正規表現要素をまとめるというカッコの 特別な意味は失われてしまうということに注意してください。

ではどうすれば?
Perl 5拡張が使えるのなら、 戻り読みで対処できます。

陥りやすい罠
[亜-腕]とか [弌-熙] とか [亜-熙]といったものは、 それぞれ「JIS第一水準の範囲の漢字」や「JIS第二水準の漢字」、 「漢字」を表すものとして使われることが多いものですが、 Unicodeをベースとしているシステムの場合 (5.8以降のuse encodingしたPerlなど)、 このような表記をしても期待通りの動作をすることはありません。 なぜなら、Unicode (or ISO 10646/JIS X 0221)では漢字の並べ方が これまで用いられてきたJIS X 0208 のそれとは異なるためです。

(regexp)
\(regexp\)

(と)で囲むことにより、ある一部分の文字列や正規表現を ひとまとめに扱うことができます。 たとえば(bang)+という正規表現は、bangやbangbang、bangbangbang という文字列にマッチします。bang+としたときとどのように違うかを 確かめてみてください。

\(\)は、sed、grep、ed等 BREで使用される書き方で、働きは()と同じですが、 BREでは後方参照を行うための指定にもなります。 GNU grepの-Eオプション指定時では()も同様の働きをしますが、POSIX 1003.2 で規定されているEREでは後方参照が使えるという記述はありません。

{n,m}
{n,}
{n}
\{n\}
\{n,\}
\{n,m\}

m、nにはそれぞれ数値が入ります。数字が nだけの場合は、ちょうどn回の繰り返し の指定になります。{n,}という形の場合ではn回以上の繰り返し、{n,m}では nは繰り返しの下限、mは上限の指定となります。 たとえば{3,5}では(直前の正規表現の)3回から5回の繰り返しになります。 ですから、

hel{3,5}o

は helllo, hellllo, helllllo にマッチしますが、helloにはマッチ しません。 \{\}はsed、grep等で使用される書き方で、働きは{}と同じです。

繰り返しの回数は処理系ごとに制限があります。最も厳しい場合で255回 程度が最大値となります。あまり大きな数字は使えないと考えたほうが 良いでしょう。また、負の数を指定することは許されません。 最大値ですが、PerlやRuby1.8で32766、GNU grepやGNU sedで32767、 PCREで65535あたりです。(Pythonでは4294967295(32bitの無符号整数の最大値) まで可能?)

{m,n}?
{n,}?
{n}?

{m,n}等と同様ですが、 マッチングがものぐさ(non-greedy)に行われる点が異なります。

^

文字列の先頭にマッチします。^cryptは cryptにマッチしますが、 encryptにはマッチしません。処理系やモードによっては文字列中の改行の 直後(つまり行の始め)にもマッチします。

$

文字列の末尾にマッチします。たとえば go$はgoとマッチしますが、 goldにはマッチしません。処理系やモードによっては文字列中の改行の 直前(つまり行の終わり)にもマッチします。これは「アンカー」であり、 改行を表す文字そのものにマッチするのではないということに注意してください。

\<
\m,[[:<:]]

“単語”の先頭にマッチします。たとえば \<away は awayにマッチ しますが、farawayにはマッチしません。

Tclでは\mまたは[[:<:]]を使います。

\>
\M,[[:>:]]

“単語”の末尾にマッチします。ですから、gnu\>はgnuに マッチしますが、cygnusにはマッチしません。

Tclでは\Mまたは[[:>:]]を使います。

[:classname:]

POSIX1003.2ではキャラクタクラス指定のときに、 名前によるキャラクタークラスの指定ができるようになりました。 現在決められているものとそれぞれ意味は次のようになっています。これらのほかに そのときのロカールによって、ロカール依存のキャラクタクラスが使える場合があります。

POSIXキャラクタクラス
クラス名 意味
[:alnum:] アルファベットと(十進)数字
[:alpha:] アルファベット
[:blank:] 空白文字(スペース、タブ等)
[:cntrl:] 制御文字
[:digit:] 十進数字
[:graph:] 印字可能かつ表示可能な文字(スペースは印字可能だが表示可能ではない)
[:lower:] アルファベットの小文字
[:print:] 印字可能なキャラクタ(=制御文字以外のキャラクタ)
[:punct:] 句読点(通常の文字、数字、制御文字、スペースのいずれでもないキャラクター)
[:space:] スペース、タブ、改ページ
[:upper:] アルファベットの大文字
[:xdigit:] 十六進数字

これらは実際に使用するときには[[:lower:]]のような形になります (ブラケットが二重になることに注意してください)。 キャラクタークラスの名称は、Cライブラリ関数のisxxx(ここで、 xxxには上記のキャラクタークラスの名称が入ります)で識別されるのと 同じ集合を表します。[^:alnum:]のような否定形を使える処理系もあります。

注意すべきこととして、これらが実際に使用時に 表す文字集合は、その時点におけるロカール(locale)に影響される可能性 があるということです。例えば、ASCIIの場合には [A-Z]と[[:upper:]]、 [A-Za-z]と[[:alpha:]]などはそれぞれまったく同じ集合を表しますが、 非ASCII環境においては、[A-Z]がASCIIと同じ集合を表すのに対して、 ウムラウトやアクサングラーブなどがついた文字が [[:...:]]の方には含まれる可能性があります。 更に言えば、EBCDICなどの環境にあっては[A-Z]が正しく「AからZまでの 大文字」という集合を表さない可能性があるのに対し、[[:upper:]]は そうではありません。

Perl(5.6以降)および PCRE には[:word:] (単語構成文字にマッチ)があります。

幾つかのドキュメントで、[:blank:]がGNU拡張であるという記述がありますが、 手元にあるPOSIX 1003.2のドキュメントには[:blank:]の項目があります。 また、LC_CTYPEの設定により任意のキャラクタクラスを認識するようにしても良い ことになっています。

\w

“単語”を構成するキャラクタ、つまり文字と数字それにアンダースコア のいずれかにマッチします。これは[[:alnum:]]と同じ意味になります。 [[:alnum:]] 同様、localeに影響される可能性に注意してください (処理系のバージョン、設定によるので詳細はここでは書きません)。

\W

“単語”を構成するキャラクタ以外のキャラクタの いずれかにマッチします。これは これは[^[:alnum:]](もしあれば[[^:alnum:]])と同じ意味になります。 また、localeに影響される可能性に注意してください。

\b
\y

“単語”の先頭、あるいは末尾にマッチします。言い換えれば、 “語の区切り”とマッチするということです。たとえば \bball\bは、前後に空白のある ball にはマッチしますが、baseballには マッチしません。

gawk 3.0.xでは、\bがバックスペースを表すエスケープシーケンスと 衝突するため、この演算子は \y となっています。Tclでも\yを使います。

\B
\Y

“単語”の中にある空文字列にマッチします。例を挙げると、 \Bgnu\Bは cygnus にはマッチしますが、gnuにはマッチしません。

一部の実装を除き、"a  "(aの後に空白二つ)が" \B "に マッチするようです(単語の境界にない空文字列にマッチ)。

Tclでは\Yを使用します。

\d

perl等で使用されるもので、[0-9]と同じ意味、つまり任意の十進数字と マッチします。 これについても locale に影響される可能性があります (たとえば 一、二、三 といった文字にもマッチしたりとか)。

\D

\dと似ていますが、意味は[^0-9]、つまり十進数字以外の任意の一文字 とマッチします。

\s

「空白」一文字とマッチする正規表現演算子です。これもlocaleの影響に注意。 とくに Unicode でいう「空白」にはいろいろなものがあります。

\S

「空白以外」の一文字とマッチする正規表現演算子です。

\C

常に「1バイト」にマッチします。

\X

基本文字に続く任意個の合成文字で表されるUnicodeキャラクタにマッチします。

\A

^と似た働きをしますが、大きな違いは ^が文字列中に埋め込まれた改行の直後にもマッチする場合があるのに対して、 この演算子は常に文字列の先頭にのみマッチするということです。

\Z

$と似ていますが、異なるのは$が文字列中に埋め込まれた改行の 直前にもマッチすることがあるのに対して、この演算子は基本的には 文字列の末尾にのみマッチするという点です。ただし 文字列の最後の文字が改行であるとき、\Zは最後の改行の 直前にマッチします。したがって

   foo\Z
   foo\n

(ここで\nは埋め込みの改行)にはマッチしますが、

   foo\n\n

にはマッチしません。

\z

Perl 5.005で導入されたもので、\Zと似ていますが、\Zが文字列 末尾の改行の直前にもマッチするのに対して、この演算子は 文字列の末尾にのみマッチするという点が異なります。

\G

文字列の先頭もしくは(グローバル指定時の)前のマッチが終了した 位置にマッチします。

\`

バッファの先頭にマッチします。^は処理系によっては 改行の直後にもマッチしますが、この演算子はそういった場所には マッチしません。

\'

バッファの末尾にマッチします。$は処理系によっては 改行の直前にもマッチしますが、この演算子はそういった場所には マッチしません。

\1 \2 \3 \4 \5 \6 \7 \8 \9

これらはそれに先行して現れた\(\)(または())で囲まれた部分正規表現に 実際にマッチしている文字列を 表します。\に続く数字は、正規表現全体の中でそれが現れた 順番を示します。たとえば\1は最初に現れた部分正規表現に 対する参照であり、\7であれば七番目のものです。 この指定は、Perl、Ruby、Tcl、PCREは九番目を越える指定が可能です。 ただし、対応する部分正規表現があることが条件になります。また、 数字部分が0で始まってはいけません。8進数値指定との区別がつかないためです (注: PythonとPCREも、99までの指定ができます)。 たとえば \(abc|123\)def\1という正規表現では、 \1はabcか、123のいずれかになります。

Pythonでは、曖昧さをなくすために\g<num>という 表記が使えます。Perlではブレースを使って${1}のようにします。

\

\は厳密には正規表現演算子ではありません。しかし、 上述した正規表現演算子を文字そのものとして扱いたいような 場合に、その前に\を置くことによって演算子の働きを 抑制することができます。たとえば、\[は[というキャラクタ そのものに対する指定であって、キャラクタクラスの始まりを 示すものではありません。

[.string.]
[=char=]

[..]は collating symbol(照合シンボル)と呼ばれる 演算子で、[.と.]に挟まれたキャラクタ列を一つの照合要素 とみなすように指定します。 たとえば [.ch.]+は c か h の(任意の組み合わせの)繰り返しではなく、 chchのような繰り返しにマッチします。 一方[==]は equivalence class(等価クラス)と呼ばれるもので、 [=と=]の間にあるキャラクタと“等価”なキャラクタにマッチします。 たとえば[=e=]としたときに、 è、 é、 ê、 ë といったもの も含まれるという指定ができます。

現状では、Perl、PCREのように認識はするが動作はしないという実装が 主流のようです(Tclでは使える?)。

glibcでもコードとしては入っているようです。どのように使えるのかは 確かめていません。

(?# text)

正規表現中に置くコメントです。括弧内にあるものは マッチングには関係しません。

拡張モード時には、#から行末までがコメントになります。

(?imsx-imsx:pattern)
(?imsx-imsx)

正規表現のオプションを指定します。これを使うことによって オプションを以降の正規表現に部分的に適用することが可能となります。 i,s,m,xはそれぞれ独立に使用できます。-が先行している場合には そのオプションを打ち消す意味になります。(?:)はそのかっこに囲 まれた範囲に影響が限定されます。前者では以降のすべてに影響が及びます (このオプション指定が存在していない処理系もあります。 詳細は処理系のドキュメントを参照してください)。 Rubyではsオプションはありません。またmオプション指定時の動作は改行が'.'に マッチするようになります。 i,s,m,xのそれぞれの意味は以下のとおり。シングルラインモードおよび マルチラインモード についての詳細はそれぞれの処理系のドキュメントを参照してください。

正規表現修飾子の意味
修飾子 意味
i 大小文字の違いを無視する
s シングルラインモードにする(.が改行にマッチする)
m マルチラインモードにする(^と$が改行の直前直後にマッチ)
x 拡張表記を許可する

Pythonにはロカール依存を有効にするL修飾子と \w, \W, \b, \B の意味をUnicode のキャラクタプロパティに基づいたものにする u修飾子があります。

PCREには通常のマッチとものぐさマッチの指定とを逆転する(?U) オプションとPCRE_EXTRAモードを有効にする(?X)オプションがあります。PCRE_EXTRA モードでは、定義されていないバックスラッシュシーケンスがエラーになります。

Pythonで使用できる正規表現修飾子は下表のとおりです。

Pythonの正規表現修飾子の意味 修飾子対応するオプション意味 iIGNORECASE (I)大小文字の違いを無視する mMULTILINE (M)マルチラインモードにする(^と$が改行の直前直後にマッチ) sDOTALL (S)“.”が改行文字にマッチ xVERBOSE (X)拡張表記を許可する uUNICODE (U)\w \W \b \BがUnicodeの英数定義に従う lLOCALE (L)\w \W \b \Bがカレントのロカールでの英数定義に従う

Rubyで使用できる正規表現修飾子は下表のとおりです。

Rubyの正規表現修飾子の意味 修飾子対応するオプション意味 iRegexp::IGNORECASE大小文字の違いを無視する mRegexp::MULTILINEマルチラインモードにする(^と$が改行の直前直後にマッチ) xRegexp::EXTENDED拡張表記を許可する

.NET Frameworkで使用できる正規表現修飾子は下表の通りです。

.NETの正規表現修飾子の意味
修飾子対応するオプション意味
iRegexOptions.IgnoreCase大小文字の違いを無視する
sRegexOptions.Singlelineシングルラインモードにする(.が改行にマッチする)
mRegexOptions.Multilineマルチラインモードにする(^と$が改行の直前直後にマッチ)
nRegexOptions.ExplicitCapture(?...) で陽に名前付けまたは番号付けしたグループだけを有効なキャプチャにするように指定する。
xRegexOptions.IgnorePatternWhitespace拡張表記を許可する

Javaのjava.util.regexで使用できる正規表現修飾子は下表の通りです。

Javaの正規表現修飾子の意味
修飾子対応するオプション意味
iCASE_INSENSITIVE大小文字の違いを無視する
dUNIX_LINESUnixラインモードにする
sDOTALLシングルラインモードにする(.が改行にマッチする)
mMULTILINEマルチラインモードにする(^と$が改行の直前直後にマッチ)
uUNICODE_CASEUnicodeに準拠した大小文字を区別しないマッチングを指定する
xCOMMENTS拡張表記を許可する
(?:regexp)

部分正規表現のグルーピングを行いますが、 \( \)や()とは異なり 後方参照を行うことはできません。たとえば、 foo(?:bar)bazfoobarbazという文字列にマッチしますが、 foo(bar)bazの場合とは異なり、\1(またはそれに相当するもの)には なにもセットされません。

(?=regexp)

括弧内にある正規表現が続くことを要求する表明です。 マッチの結果の文字列には影響しません。 例えば、else(?= if)という正規表現は “else if” にマッチし ますが、Perlの$&のような正規表現全体にマッチした文字列は “else”となります(当然ながら、“ if”が後続していない “else”にはマッチしません)。

よくある勘違い
(?=foo)bar のように記述しても、「fooのあとにbarが続いている文字列」には なりません。 fooを先読みしてマッチのポイントは動かしませんので(それが先読みだから)、 その場所にbarがあるかどうかで判断します。マッチのポイントより 前にある文字列が存在するかどうかという判定ではありません (それをするのは戻り読み)。

(?!regexp)

(?=regexp)と似ていますが、 こちらは括弧内にある正規表現が続かないことを要求する 表明です。

肯定先読み と同様に、「ある文字列が先行していない文字列にマッチ」 させるためにこの表明を使うことはできません。

(?<=pattern)

括弧内にある正規表現が先行していることを要求する表明です。 マッチの結果の文字列には影響しません。例えば、(?<=\t)\wという 正規表現はタブに続く単語にマッチしますが、マッチした文字列全体を表す $&(Perlの場合)にはタブは含まれ ません。戻り読み (もしくは後読み (lookbehind))は 固定長の文字列に対してのみ働きます(処理系による。可変長の文字列を許可 する処理系もあります→ 詳細)。

(?<!pattern)

括弧内にある正規表現が先行していないことを要求する表明です。 マッチの結果の文字列には影響しません。例えば、(?<!foo)barという 正規表現はfooが先行しないbarにマッチしますが、マッチした文字列全体を表す $&(Perlの場合)には fooは含まれません。 後読み(もしくは戻り読み (lookbehind))は固定長の文字列に対してのみ 働きます(処理系による。可変長の文字列を許可する処理系もあります)。

(?>pattern)

一旦マッチした部分正規表現をバックトラックすることのないパターン です。したがって、(?>a+)abは何にもマッチしません。カッコ内のパターン がすべてのaを消費し、それを手放さないためです。

(?(condition)yes-pattern|no-pattern)
(?(condition)yes-pattern)

条件式です。(condition)は、括弧の中に置かれた整数(対応するかっこのペアが マッチしているときに正当)もしくは長さゼロの lookahead/lookbehind/evaluate 表明であることが望ましいです。

Pythonでは表明は使えません。.NETでは名前による後方参照の指定ができます。

(?{ code })

Perlにおいて、埋め込まれたPerlコードを実行します

(??{ code })

Perlにおいて、埋め込まれたPerlコードを実行してその結果を正規表現を表すものとして 使用します。

*+

*に似ていますが、決してバックトラックしません。

++

+に似ていますが、決してバックトラックしません。

?+

?に似ていますが、決してバックトラックしません。

{n,m}+
{n,}+
{n}+

{n,m}等に似ていますが、決してバックトラックしません。

(?P<name>...)
(?<name>...) (?'name'...)

マッチした文字列を name という名前で参照できるようにします。

(?<name>...) や (?'name'...)は .NETで使用される表現です

(?P=name), \g<name>
\k<name> \k'name'

対応する(?P<name>...) でキャプチャした文字列を参照します。\g<name> は置換テキスト中で使う表現です。

\k<name> や \k'name'は .NETで使用される表現です

(?P>name)

対応する(?P<name>...) でキャプチャした文字列を参照します。PCREの再帰的表現で使用します。 以下に使用例を挙げます。バランスの取れた括弧の対にマッチします。

    (?P<pn>\(((?>[^()]+)|(?P>pn))*\))
(?<name1-name2>)

グループ定義を均等化します。既に定義されていたグループ name2 の定義を削除し、既に定義されていた name2 グループと現在のグループの間隔をグループ name1 に格納します。グループ name2 が定義されていない場合、一致はバックトラックされます。name2 の最後の定義を削除すると、name2 の以前の定義がわかるため、この構成体によって、かっこなど入れ子になった構成体を追跡するカウンタとしてグループ name2 のキャプチャのスタックを使用できます。この構成体では、name1 は省略できます。たとえば (?'name1-name2') のように、山かっこの代わりに一重引用符を使用することもできます。 (グループ化構成体より)

(?R)

PCREで、再帰的にパターンにマッチする表現です。

(?num)

PCREで、再帰的にパターンにマッチする表現です。 (?R)に似ていますが、 こちらはパターン全体ではなくnumに対応する キャプチャされた部分正規表現が再帰の対象です。この例もバランスの取れた 括弧の対にマッチします。

    (\()?[^()]+(?(1)\))

次のような使い方もできます。

    (sens|respons)e and (?1)ibility

これは \1 を使ったものとは異なり、sense and responsibility にもマッチします。

(?(R)...)

PCREで、再帰的パターンの開始を示します。

    <(?:(?(R)\d++|[^<>]*+)|(?R))*>
\p{name}, \P{name}

ブレースに囲まれた名前で指定されたキャラクタ集合に属するキャラクタを指定します。 指定できるキャラクタ集合は一般に、Unicodeのプロパティ、スクリプト、ブロック、カテゴリです。 処理系によっては使える集合が制限されていたりします。

各エスケープシーケンスの説明

正規表現リテラル中で使えるエスケープシーケンスです。 文字列中で使えるものと共通しているもの、していないものがあります。

\a

警告(ベル)です。

\b

バックスペースを表しますが文字クラス内に制限される処理系があります。

\e

エスケープ文字。Perl、PCREで使えます。

\n

改行。

\r

キャリッジリターン。

\f

改ページ。

\t

水平タブです。

\octal

2~3桁の8進表現文字です。数値が3桁ない場合0を数値に前置します (後方参照と区別するため)。

\xhex
\xxxx

16進表現文字です。何桁の表記か可能かどうかが処理系によって異なる場合があります (1桁でも可とか)。

\x{hex}

Perl等で使えるもので任意長の16進表現文字です。

\cchar

Perl等で使えるもので、制御キャラクタをあらわします。 例えば \ci は水平タブになります。

\c[ や \c\ はそのままでは記述できない場合があります。 文字クラスの中に入れたり、\c\\のようにすることで回避できる場合があります。

\C-char

Rubyで使えるもので、制御キャラクタをあらわします。例えば \C-jは改行コードになります。

\M-char

Rubyで使えるもので、charと\x80をbitwise or した コードになります。例えば \M-@ は\xc0と等価です。Emacsでいうところの メタな文字です(正規表現のメタキャラクタと混同しないように)。

\uhhhh
\Uhhhhhhhh

Pyhton、Tcl等で使えるもので、それぞれ四桁、八桁の16進数表現文字です。Perlでは\u、\U とも別の意味があります。

\N{name}

Perl、Pythonで使えるもので名前付けられたキャラクタを表します。詳しくは charnamesを 参照してください。

\R
Ruby において、改行文字を表すもの
\X
Ruby において、Unicode の結合文字シーケンスを表すもの

ある文字列を含まない正規表現

提案から実装まで 9 年も掛かってしまいましたが、 鬼車の中の人と Ruby の間の確執がなければとっくの昔に実装されていたのだろうかと思ったり思わなかったり。 ( 鬼雲に非包含オペレータを実装した話 - Qiita)

おにいさん、それは言わないヤクソク……


Dr. Regex: For Regex Purists: Can Formal Regular Expressions Be Fun?


その他

Are Regular Expressions a Lingua Franca? An Empirical Study on the Re-use and Portability of Regular Expressions : programming 経由で Are Regular Expressions aLingua Franca?An Empirical Study on the Re-use and Portability of Regular Expressions からABSTRACT をちょっと抜き出し。

ABSTRACT

This paper explores the extent to which regular expressions (regexes)are portable across programming languages. Many languages of-fer similar regex syntaxes, and it would be natural to assume thatregexes can be ported across language boundaries. But can regexesbe copy/pasted across language boundaries while retaining theirsemantic and performance characteristics? In our survey of 159 professional software developers, most in-dicated that they re-use regexes across language boundaries and about half reported that they believe regexes are a universal lan-guage. We experimentally evaluate the riskiness of this practiceusing a novel regex corpus — 537,806 regexes from 193,524 projectswritten in JavaScript, Java, PHP, Python, Ruby, Go, Perl, and Rust. Using our polyglot regex corpus, we explore the hitherto-unstudiedregex portability problems: logic errors due to semantic differ-ences and security vulnerabilities due to performance differences. We report that developers’ belief in a regexlingua francais un-derstandable but incorrect. Though most regexes compile acrosslanguage boundaries, 15% exhibit semantic differences across lan-guages, and 10% exhibit performance differences across languages. We explained these differences using regex documentation, andfurther illuminate our findings by investigating regex engine im-plementations. Along the way we found bugs in JavaScript-V8,Python, Ruby, and Rust, as well as thousands of modules affected by potential semantic and performance regex bugs.Regexes are not alingua franca— almost, but not quite.


ホームページへ

この文書の無断転載はご遠慮ください。リンクについてはご自由にしていただいてかまいません。 質問、指摘等は kbk AT kt DOT rim DOT or DOT jp まで。