エスケープシーケンス

バックスラッシュ〔日本語環境では円記号となる場合もある〕には、 いくつかの使用法があります。ひとつめの使用法は、 非英数字の前に記述する場合で、続く文字が表す特別な意味を取り去ります。 このエスケープ文字としての使用法は、 文字クラスの内外部いずれでも可能です。

たとえば、"*" 文字とマッチさせたい場合は、パターンを "\*" と記述します。 続く文字がメタ文字として解釈されるものであるかには関係ありませんので、 いかなる非英数字に対しても、"\" を付けると、その文字自体が 表わされることになります。特に、 バックスラッシュとマッチさせたい場合は、"\\" と記述します。

注意:

シングルクォートあるいはダブルクォートで囲まれた PHP の 文字列 の中では、バックスラッシュは特別な意味を表します。 そのため、正規表現 \\ を使用して \ とマッチさせたい場合は PHP のコード内では "\\\\" あるいは '\\\\' と記述する必要があります。

パターンを、 PCRE_EXTENDED オプションを付けてコンパイルすると、(文字クラス内部を除き) パターン中の空白文字、および "#" とその次の改行文字との間の文字は 無視されます。空白文字や "#" をパターン中に含めるには、 バックスラッシュを用いてエスケープします。

バックスラッシュの 2 番目の使用法は、非表示文字〔制御コードなど〕を パターン中に目に見える形で記述するための方法です。ヌル文字は パターンを終了させてしまうため使えませんが、その他の非表示文字は、 パターンにそのまま含めても問題はありません。しかし、パターンの編集には、 バイナリ文字をそのまま用いるよりも、以下に示すエスケープシーケンスを 用いる方が便利でしょう。

\a
アラーム、ベル文字 (16進 07)
\cx
"control-x", ここで x は任意の文字
\e
エスケープ文字 (16進 1B)
\f
改ページ (formfeed) (16進 0C)
\n
改行 (newline) (16進 0A)
\p{xx}
xx プロパティを持つ文字、詳細は unicode プロパティ を参照
\P{xx}
xx プロパティを持たない文字、詳細は unicode プロパティ を参照
\r
復帰 (carriage return) (16進 0D)
\R
改行: \n、\r、\r\n にマッチする
\t
タブ (16進 09)
\xhh
16 進コードで hh の文字
\ddd
8 進コードで ddd の文字、もしくは、後方参照

"\cx" の正確な働きは、次の通りです。 "x" が小文字の場合、 大文字に変換されます。続いて、文字の 6 ビット目 (16進数 40) が 反転されます。つまり、"\cz" は 16 進数の 1A になり、 "\c{" は 3B になり、 "\c;" は 7B になります。

"\x" の後では、2 桁までの 16 進数が読まれます (大小文字どちらも可能です)。 UTF-8 モード では、 "\x{...}" という記法も使えます。 この場合、波括弧の中身は16進数を示す文字列です。 この文字列は、16進数の数値でコードポイントを表す UTF-8 文字として解釈されます。 オリジナルの16進のエスケープシーケンス \xhh は、 値が127より大きい場合、2バイトのUTF-8 文字とマッチします。

"\0" の後では、さらに 2 桁の 8 進数が 読みこまれます。いずれの場合も、2 桁より少ない場合、桁があるだけ 読みこまれます。つまり、"\0\x\07" は ヌル文字 2 つの後にベル文字が 続いたものを表します。8 進数を指定する場合は、必ず最初のゼロに続いて 残りの 2 桁の数字を指定するように注意してください。

バックスラッシュの後に 0 以外の数字が続く場合の処理は複雑です。 文字クラスの外部では、 PCRE は、続く数字全体を 10 進数として読みます。 数字が 10 よりも小さい場合、または、正規表現の中に含まれる キャプチャ用左カッコの数以下の場合、 後方参照 として解釈されます。 この動作に関する詳しい説明は、後ほど、カッコによるサブパターンの説明を 行ってから示します

文字クラスの中、または、指定された 10 進数が 9 より大きく、 キャプチャ用サブパターンの数がこの数に満たない場合は、PCRE は バックスラッシュの後から最大 3 文字の 8 進数を再度読みこみ、 その値の最下位 8 ビットから 1 バイトを生成します。 その後に続く数字は、それ自体を表します。以下に例を示します。

\040
スペースの別の表記法
\40
上と同じ。ただし、キャプチャ用サブパターンが 40 個未満の場合
\7
常に後方参照
\11
後方参照、または、タブの別記法
\011
常にタブ
\0113
タブの後に文字 "3" が続いたもの
\113
8進コードで 113 の文字 (99 を超える後方参照は存在しないため)
\377
全ビットが 1 である 1 バイト
\81
後方参照、または、ヌル文字の後に 2つの文字 "8" および "1" が続いたもの

3 桁を超えて 8 進数は読みこまれないため、100 以上の 8 進数には ゼロを前につけてはいけないことに注意してください。

これらの 1 バイト値を定義するエスケープシーケンスは、 文字クラスの内外部のいずれでも使用できます。加えて、文字クラス内では エスケープシーケンス "\b" はバックスペース (16進 08) として解釈されます。 文字クラス外では、別の意味を有します(別記参照)。

バックスラッシュの第 3 の使用法は、包括的な文字型を指定する用途です。

\d
10 進数字
\D
10 進数字でない文字
\h
水平方向の空白文字
\H
水平方向の空白文字でない文字
\s
空白文字
\S
空白文字でない文字
\v
垂直方向の空白文字
\V
垂直方向の空白文字でない文字
\w
単語構成文字 (word character)
\W
非単語構成文字 (non-word character)

これらエスケープシーケンスの各組により、文字集合が 2 つに分割されます。 文字は、各組のどちらか片方だけにマッチします。

空白文字とは HT (9)、LF (10)、FF (12)、CR (13)、スペース (32) のことです。 しかし、ロケールを指定したマッチングを行った場合には、 128から255までのコードポイントの文字 (たとえば NBSP (A0)) も空白文字とみなされる可能性があります。

単語構成文字とは、英字または数字またはアンダースコア文字であり、Perl が定義するところの「単語」と成り得る文字のことです。文字および数字の 定義は、PCRE の文字テーブルにより制御され、ロケールを指定して マッチングを行うと変わる可能性があります。 例えば、"fr" (フランス語)ロケールの場合、128 を超える 文字コードのいくつかは、アクセント付きの文字に使われており、 これらは \w とマッチします。

これらの文字型表記は、文字クラスの内外によらず使用可能で、 対応する型のたかだか 1 文字とマッチします。現在のマッチング位置が 検索対象文字列の終端である場合、マッチできる文字が無いので、 マッチは失敗します。

バックスラッシュの第 4 の使用法は、簡単な言明 (assertion) です。 言明とは、マッチがある特定の位置でだけ可能だという条件を指定するもので、 検索対象文字列から文字を消費 (consume)〔つまり文字自体にマッチ〕 しません。サブパターンを使ったより複雑な言明の方法もありますが、 それについての解説は後ほど行います。バックスラッシュを使った言明は、 次のものがあります

\b
単語境界
\B
非単語境界
\A
検索対象文字列の始端(複数行モードとは独立)
\Z
検索対象文字列の終端、または終端の改行(複数行モードとは独立)
\z
検索対象文字列の終端(複数行モードとは独立)
\G
マッチングの開始位置

これらの言明は、文字クラス内では使用できません(また、文字クラス内では、 "\b" はバックスペース文字という別の意味を持つので 注意してください)。

単語境界 (word boundary) とは、検索対象文字列において、 カレントの文字およびその前の文字が同時に \w もしくは \W にマッチしない(すなわち、片方が \w にマッチし、もう片方が \W にマッチする)位置、もしくは、文字列の始めか終わりで、 その始めか終わりの文字が \w にマッチする位置の ことです。

言明 \A, \Z, \z は、(アンカー で説明する)ハット記号やドル記号とは 異なり、オプション設定によらず、文字列の始端または終端だけに マッチします。これらの言明は、PCRE_MULTILINE および PCRE_DOLLAR_ENDONLY オプションの影響を受けません。 \Z\z との違いは、 \Z は文字列の末尾の改行の前の位置および文字列の 終端にマッチするのに対し、\z は文字列の終端にのみ マッチすることです。

言明 \G は、カレントのマッチング位置が、 preg_match() 関数の offset 引数に指定されたマッチングの開始位置である場合に真になります。 offset が非ゼロの場合は、\A と等価ではありません。

\Q\E とを使って、 パターン中のメタ文字を無視させることができます。 たとえば、 \w+\Q.$.\E$ は、文字列の終端において1つ以上の単語構成文字のあとに .$. というリテラルが続いたものにマッチします。 これらは、デリミタの動作を変更しないことに注意して下さい。 たとえば、#\Q#\E#$ は無効なパターンです。 なぜなら、# がパターンの終端としてマークされ、 \E# が無効な修正子と解釈されるからです。

\K を使用すると、マッチの開始位置をリセットできます。 たとえば、パターン foo\Kbar は "foobar" にマッチしますが、 結果は "bar" にマッチしたと報告されます。 \K を使用しても、キャプチャした部分文字列には影響を及ぼしません。 たとえば、パターン (foo)\Kbar が "foobar" にマッチしたときの最初の部分文字列は "foo" です。

add a note add a note

User Contributed Notes 6 notes

up
53
mike at eastghost dot com
12 years ago
"line break" is ill-defined:

-- Windows uses CR+LF (\r\n)
-- Linux LF (\n)
-- OSX CR (\r)

Little-known special character:
\R in preg_* matches all three.

preg_match( '/^\R$/', "match\nany\\n\rline\r\nending\r" ); // match any line endings
up
8
Wirek
6 years ago
Significantly updated version (with new $pat4 utilising \R properly, its results and comments):
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq) when used improperly.
A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
//          C          3                   p          0                   _
$pat1='/\w$/mi';    // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi';    // Slightly better
$pat3='/\w\R?$/mi';    // Somehow disappointing according to php.net and pcre.org when used improperly
$pat4='/\w(?=\R)/i';    // Much better with allowed lookahead assertion (just to detect without capture) without multiline (/m) mode; note that with alternative for end of string ((?=\R|$)) it would grab all 7 elements as expected
$pat5='/\w\v?$/mi';
$pat6='/(*ANYCRLF)\w$/mi';    // Excellent but undocumented on php.net at the moment (described on pcre.org and en.wikipedia.org)
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
$t=preg_match_all($pat6, $str, $m6);
echo
$str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
    .
"\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
    .
"\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
    .
"\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
    .
"\n5 !!! $pat5 ($s): ".print_r($m5[0], true)
    .
"\n6 !!! $pat6 ($t): ".print_r($m6[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 and $pat4 (\R), $pat5 (\v) and altered newline option in $pat6 ((*ANYCRLF)) - for some applications at least.

/* The code above results in the following output:
ABC ABC

123 123
def def
nop nop
890 890
QRS QRS

~-_ ~-_
1 !!! /\w$/mi (3): Array
(
    [0] => C
    [1] => 0
    [2] => _
)

2 !!! /\w\r?$/mi (5): Array
(
    [0] => C
    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

3 !!! /\w\R?$/mi (5): Array
(
    [0] => C

    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

4 !!! /\w(?=\R)/i (6): Array
(
    [0] => C
    [1] => 3
    [2] => f
    [3] => p
    [4] => 0
    [5] => S
)

5 !!! /\w\v?$/mi (5): Array
(
    [0] => C

    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

6 !!! /(*ANYCRLF)\w$/mi (7): Array
(
    [0] => C
    [1] => 3
    [2] => f
    [3] => p
    [4] => 0
    [5] => S
    [6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.
up
4
Anonymous
5 years ago
A non breaking space is not considered as a space and cannot be caught by \s.

it can be found with :

- [\xc2\xa0] in utf-8
- \x{00a0} in unicode
up
9
grigor at the domain gatchev.info
13 years ago
As \v matches both single char line ends (CR, LF) and double char (CR+LF, LF+CR), it is not a fixed length atom (eg. is not allowed in lookbehind assertions).
up
-1
tharabar at gmail dot com
5 years ago
Required to use \007 instead of \a
up
-4
Wirek
6 years ago
Note that there are (sometimes difficult to grasp at first glance) nuances of meaning and application of escape sequences like \r, \R and \v - none of them is perfect in all situations, but they are quite useful nevertheless. Some official PCRE control options and their changes come in handy too - unfortunately neither (*ANYCRLF), (*ANY) nor (*CRLF) is documented here on php.net at the moment (although they seem to be available for over 10 years and 5 months now), but they are described on Wikipedia ("Newline/linebreak options" at https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions) and official PCRE library site ("Newline convention" at http://www.pcre.org/original/doc/html/pcresyntax.html#SEC17) pretty well. The functionality of \R appears somehow disappointing (with default configuration of compile time option) according to php.net as well as official description ("Newline sequences" at https://www.pcre.org/original/doc/html/pcrepattern.html#newlineseq).

A hint for those of you who are trying to fight off (or work around at least) the problem of matching a pattern correctly at the end ($) of any line in multiple lines mode (/m).
<?php
// Various OS-es have various end line (a.k.a line break) chars:
// - Windows uses CR+LF (\r\n);
// - Linux LF (\n);
// - OSX CR (\r).
// And that's why single dollar meta assertion ($) sometimes fails with multiline modifier (/m) mode - possible bug in PHP 5.3.8 or just a "feature"(?).
$str="ABC ABC\n\n123 123\r\ndef def\rnop nop\r\n890 890\nQRS QRS\r\r~-_ ~-_";
//          C          3                   p          0                   _
$pat1='/\w$/mi';    // This works excellent in JavaScript (Firefox 7.0.1+)
$pat2='/\w\r?$/mi';
$pat3='/\w\R?$/mi';    // Somehow disappointing according to php.net and pcre.org
$pat4='/\w\v?$/mi';
$pat5='/(*ANYCRLF)\w$/mi';    // Excellent but undocumented on php.net at the moment
$n=preg_match_all($pat1, $str, $m1);
$o=preg_match_all($pat2, $str, $m2);
$p=preg_match_all($pat3, $str, $m3);
$r=preg_match_all($pat4, $str, $m4);
$s=preg_match_all($pat5, $str, $m5);
echo
$str."\n1 !!! $pat1 ($n): ".print_r($m1[0], true)
    .
"\n2 !!! $pat2 ($o): ".print_r($m2[0], true)
    .
"\n3 !!! $pat3 ($p): ".print_r($m3[0], true)
    .
"\n4 !!! $pat4 ($r): ".print_r($m4[0], true)
    .
"\n5 !!! $pat5 ($s): ".print_r($m5[0], true);
// Note the difference among the three very helpful escape sequences in $pat2 (\r), $pat3 (\R), $pat4 (\v) and altered newline option in $pat5 ((*ANYCRLF)) - for some applications at least.

/* The code above results in the following output:
ABC ABC

123 123
def def
nop nop
890 890
QRS QRS

~-_ ~-_
1 !!! /\w$/mi (3): Array
(
    [0] => C
    [1] => 0
    [2] => _
)

2 !!! /\w\r?$/mi (5): Array
(
    [0] => C
    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

3 !!! /\w\R?$/mi (5): Array
(
    [0] => C

    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

4 !!! /\w\v?$/mi (5): Array
(
    [0] => C

    [1] => 3
    [2] => p
    [3] => 0
    [4] => _
)

5 !!! /(*ANYCRLF)\w$/mi (7): Array
(
    [0] => C
    [1] => 3
    [2] => f
    [3] => p
    [4] => 0
    [5] => S
    [6] => _
)
*/
?>
Unfortunately, I haven't got any access to a server with the latest PHP version - my local PHP is 5.3.8 and my public host's PHP is version 5.2.17.
To Top