文字クラス
開き角カッコは文字クラス (character class) の開始を表し、 閉じ角カッコにより文字クラスは終了します。閉じ角カッコだけでは、 特別な意味を持ちません。閉じ角カッコを文字クラスのメンバとしたい場合は、 文字クラスの最初の文字(否定のハット記号がある場合はその直後)とするか、 バックスラッシュでエスケープする必要があります。
文字クラスは、検索対象文字列のたかだか 1 文字にマッチします。 マッチする文字は、その文字クラスによって定義された文字集合のうちの どれかです。ただし、文字クラスの最初の文字がハット記号の場合は、 マッチする文字は、その文字クラスに定義されていない文字となります。 ハット記号自体をクラスのメンバとしたい場合は、文字クラスの 最初の文字としないか、バックスラッシュでエスケープしてください。
例えば、文字クラス [aeiou] は小文字の母音にマッチしますが、[^aeiou] は 小文字の母音以外の文字にマッチします。ハット記号は、含まれない文字を 列挙することにより文字クラスに含まれる文字を指定するための簡略表記です。 文字クラスは、言明ではありません。対象文字列から文字を消費します。また、 カレントのポインタが文字列の終端にある場合には、マッチに失敗します。
大小文字を区別しないマッチングを行うよう設定した場合は、 クラス内の文字は大小文字の両方を表します。例えば、 大小文字を区別しない場合、[aeiou] は "a" にも "A" にもマッチします。 同じく大小文字を区別しない場合 [^aeiou] は "A" にマッチしませんが、 区別する場合はマッチします
PCRE_DOTALL または PCRE_MULTILINE オプションをどのように設定しようとも、改行文字は、文字クラスにおいて 特別な扱いはされません。たとえば、 [^a] のようなクラスは、 常に改行にマッチします。
マイナス (ハイフン) 記号は、文字クラスで文字の範囲を指定するために 使われます。例えば、[d-m] は d と m の間のあらゆる文字にマッチします。 マイナス記号が文字クラス内に必要な場合は、バックスラッシュで エスケープしてください。もしくは、文字クラスの最初または最後など、 範囲を示すと解釈されない場所に記述してください。
文字リテラル "]" を、文字範囲を示す最後の文字として使うことは できません。 [W-]46] というパターンは、2 つの文字 ("W" および"-") が 含まれるクラスの後に文字列リテラル "46]" が続いていると解釈され、 "W46]" や "-46]" にマッチします。しかし、"]" をバックスラッシュで エスケープすると文字範囲の終端として解釈され、 [W-]46] は、 範囲指定の後に 2 つの文字が続く 1 つのクラスとして解釈されます。 "]" の 8 進あるいは 16 進表現も文字範囲の終端として使用可能です。
文字範囲指定では、ASCII 照合順序 (collating sequence) が用いられます 〔つまり、範囲指定する際の文字の並び順として ASCII が用いられます〕。 [\000-\037] のような、数値的な文字の指定も使用可能です。大小文字を 区別しないマッチングを行うよう設定した場合、パターン中の英字は 大小文字の両方にマッチします。例えば、[W-c] は、[][\^_`wxyzabc] に 等価であり、大小文字に関係なくマッチします。また、 "fr" ロケールの文字テーブルを使う場合、[\xc8-\xcb] は、 大小文字の区別無くアクセント付きの E にマッチします。
文字型 \d, \D, \s, \S, \w, \W も、文字クラス内で使え、 マッチする文字を追加することが可能です。例えば、[ABCDEF] は、 16進数にマッチします。ハット記号と大文字の文字型を組み合わせることで、 小文字の文字型がマッチするものより狭い文字集合を 簡便に指定することができます。例えば、クラス [^\W_] は、 〔単語構成〕文字および数字にマッチしますが、アンダースコアには マッチしません。
\, -, (始端の)^ および終端の ] 以外のすべての非英数字は、 文字クラスにおいて特別な意味を持たない文字ですが、 エスケープしても問題はありません。 パターンの終端文字は常に特別扱いされるので、 正規表現内で私用する場合は必ずエスケープしなければなりません。
Perl は、POSIX 記法の文字クラスもサポートしています。これは、
[:
と :]
で囲んだ名前を角カッコ内で使うものです。
PCRE でもこの記法に対応しています。たとえば [01[:alpha:]%]
は
"0"、"1"、任意のアルファベット、あるいは "%" にマッチします。対応しているクラス名は次のとおりです。
alnum | letters and digits |
alpha | letters |
ascii | character codes 0 - 127 |
blank | space or tab only |
cntrl | control characters |
digit | decimal digits (same as \d) |
graph | printing characters, excluding space |
lower | lower case letters |
print | printing characters, including space |
punct | printing characters, excluding letters and digits |
space | white space (not quite the same as \s) |
upper | upper case letters |
word | "word" characters (same as \w) |
xdigit | hexadecimal digits |
space
文字は HT (9), LF (10), VT (11), FF (12), CR (13),
およびスペース (32) です。この中に VT 文字 (コード 11) が含まれていることに注目しましょう。
この点で、"space" は \s
と異なります。こちらは VT を含みません
(Perl との互換性のため)。
word
は Perl 拡張で、blank
は Perl 5.8
からの GNU 拡張です。それ以外の Perl 拡張には否定があります。否定を指示するには
^
をコロンの後に続けます。たとえば
[12[:^digit:]]
は "1"、"2"、あるいは任意の非数値にマッチします。
UTF-8 モードでは、128 より大きなコードはどの POSIX 文字クラスにもマッチしません。 libpcre 8.10 以降では、 いくつかの文字クラスが Unicode 文字プロパティを使うように変わりました。 それらの文字クラスでは、ここに挙げた制約はあてはまりません。 詳細は、» PCRE(3) のマニュアル を参照ください。
Unicode 文字プロパティは、文字クラスに含めることができます。 しかし、範囲指定に含めることはできません。 マイナス (ハイフン) を Unicode 文字クラスの後に続けた場合は、その文字としてマッチします。 範囲指定を Unicode 文字プロパティで終えようとすると、警告が発生します。
User Contributed Notes 3 notes
From deep down the PCRE manual at http://www.pcre.org/pcre.txt :
\d any decimal digit
\D any character that is not a decimal digit
\h any horizontal white space character
\H any character that is not a horizontal white space character
\s any white space character
\S any character that is not a white space character
\v any vertical white space character
\V any character that is not a vertical white space character
\w any "word" character
\W any "non-word" character
Examples with Character classes
<?php
$stringA = "1 In the beginning God created the heavens and the earth.";
$stringB = preg_replace('/[[:^alnum:]]/', '', $stringA); // string(46) "1InthebeginningGodcreatedtheheavensandtheearth"
$stringC = preg_replace('/[[:^alpha:]]/', '', $stringA); // string(45) "InthebeginningGodcreatedtheheavensandtheearth"
$stringD = preg_replace('/[[:^ascii:]]/', '', "Pokémon"); // string(6) "Pokmon"
$stringE = preg_replace('/[[:^blank:]]/', '*', $stringA); // string(57) "* ** *** ********* *** ******* *** ******* *** *** ******"
$stringF = preg_replace('/[[:blank:]]/', '-', $stringA); // string(57) "1-In-the-beginning-God-created-the-heavens-and-the-earth."
$stringG = sprintf("Vertical Tabulation: %s", chr(11)); // string(22) "Vertical Tabulation: "
$stringH = preg_replace('/[[:cntrl:]]/', '', $stringG); // string(21) "Vertical Tabulation: "
$stringLengthG = strlen($stringG); // int(22)
$stringLengthH = strlen($stringH); // int(21)
$stringI = preg_replace('/[[:digit:]]/', '', 'My age is 35'); //string(10) "My age is "
$stringJ = preg_replace('/[[:^digit:]]/', '', 'My age is 35'); // string(2) "35"
$stringK = preg_replace('/[[:^graph:]]/', '', $stringG); // string(19) "VerticalTabulation:"
$stringL = preg_replace('/[[:graph:]]/', '', $stringG); // string(3) " "
$stringM = preg_replace('/[[:lower:]]/', '', $stringG); // string(6) "V T: "
$stringN = preg_replace('/[[:^lower:]]/', '', $stringG); // string(16) "erticalabulation"
$stringO = preg_replace('/[[:^print:]]/', '', $stringG); // string(21) "Vertical Tabulation: "
$stringP = preg_replace('/[[:print:]]/', '', $stringG); // string(1) ""
$stringQ = preg_replace('/[[:punct:]]/', '', $stringG); // string(21) "Vertical Tabulation "
$stringR = preg_replace('/[[:^punct:]]/', '', $stringG); // string(1) ":"
$stringS = preg_replace('/[[:space:]]/', '', $stringG); // string(19) "VerticalTabulation:"
$stringT = preg_replace('/[[:^space:]]/', '', $stringG); // string(3) " "
$stringU = preg_replace('/[[:upper:]]/', '', $stringG); // string(20) "ertical abulation: "
$stringV = preg_replace('/[[:^upper:]]/', '', $stringG); // string(2) "VT"
$stringW = preg_replace('/[[:word:]]/', '', $stringG); // string(4) " : "
$stringX = preg_replace('/[[:^word:]]/', '', $stringG); // string(18) "VerticalTabulation"
$stringY = preg_replace('/[[:xdigit:]]/', '', 'abcdefghijklmnopqrstuvwxyz0123456789'); // string(20) "ghijklmnopqrstuvwxyz"
$stringZ = preg_replace('/[[:^xdigit:]]/', '', 'abcdefghijklmnopqrstuvwxyz0123456789'); // string(16) "abcdef0123456789"
The documentation says:
"The character types \d, \D, \s, \S, \w, and \W may also appear in a character class, and add the characters that they match to the class."
It does not stress that other escape types may not. I wanted to split a string on either a comma (","), or a new line "\n". When my input stream began to include "\r\n", I decided to change "\n" to "\R". Unfortunately, my test string did not include a capital "R", or I might have found the problem sooner. My '/[\R,]/' was simply splitting on comma and the letter "R".
My test string...
"The Yum-Yum Company\r\n127 bernard street"
What DID work: '/(?:\R|,)+/'
["The Yum-Yum Company","127 bernard street"]
Given character classes only match one character, I can see clearly why my expectations were justifiably dashed, but hopefully this comment will save time for someone else.
I might add, this has taught me the value of PCRE_EXTRA (modifier "X"), which I have begun to use routinely now.