来自 PCRE 手册的深处 http://www.pcre.org/pcre.txt
\d 任何十进制数字
\D 任何不是十进制数字的字符
\h 任何水平空白字符
\H 任何不是水平空白字符的字符
\s 任何空白字符
\S 任何不是空白字符的字符
\v 任何垂直空白字符
\V 任何不是垂直空白字符的字符
\w 任何“单词”字符
\W 任何“非单词”字符
一个左方括号引入一个字符类,由一个右方括号终止。一个单独的右方括号本身并不特殊。如果需要一个右方括号作为类的成员,它应该是在类中的第一个数据字符(在初始插入符号之后,如果存在),或者用反斜杠转义。
一个字符类匹配主题中的单个字符;该字符必须在由类定义的字符集中,除非类中的第一个字符是插入符号,在这种情况下,主题字符必须不在由类定义的集中。如果实际需要插入符号作为类的成员,请确保它不是第一个字符,或者用反斜杠转义它。
例如,字符类 [aeiou] 匹配任何小写元音,而 [^aeiou] 匹配任何不是小写元音的字符。请注意,插入符号只是一个用于指定通过枚举那些不包含的字符来包含在类中的字符的便捷表示法。它不是断言:它仍然从主题字符串中消耗一个字符,如果当前指针位于字符串的末尾,则会失败。
当设置不区分大小写(无大小写)匹配时,类中的任何字母都代表它们的大写和小写版本,因此例如,不区分大小写的 [aeiou] 匹配 "A" 以及 "a",而不区分大小写的 [^aeiou] 不匹配 "A",而区分大小写的(区分大小写)版本则会匹配。
换行符在字符类中绝不会以任何特殊方式处理,无论 PCRE_DOTALL 或 PCRE_MULTILINE 选项的设置如何。像 [^a] 这样的类总是匹配换行符。
减号(连字符)字符可用于指定字符类中的字符范围。例如,[d-m] 匹配从 d 到 m 之间的任何字母(包括 d 和 m)。如果字符类中需要减号字符,则必须用反斜杠转义它,或者出现在无法解释为表示范围的位置,通常是类中的第一个或最后一个字符。
无法使用文字字符 "]" 作为范围的结束字符。像 [W-]46] 这样的模式被解释为包含两个字符("W" 和 "-")的类,后跟文字字符串 "46]",因此它将匹配 "W46]" 或 "-46]"。但是,如果 "]" 用反斜杠转义,它将被解释为范围的结束,因此 [W-\]46] 被解释为包含范围的单个类,后跟两个单独的字符。还可以使用 "]" 的八进制或十六进制表示法来结束范围。
范围在 ASCII 排序顺序中运行。它们也可以用于以数字方式指定的字符,例如 [\000-\037]。如果在设置不区分大小写(无大小写)匹配时使用包含字母的范围,它将匹配这两种情况下的字母。例如,[W-c] 等效于 [][\^_`wxyzabc],不区分大小写匹配,如果使用 "fr" 本地的字符表,[\xc8-\xcb] 将匹配两种情况下的重音 E 字符。
字符类型 \d、\D、\s、\S、\w 和 \W 也可以出现在字符类中,并将它们匹配的字符添加到类中。例如,[\dABCDEF] 匹配任何十六进制数字。可以使用插入符号与大写字符类型方便地指定比匹配的小写类型更受限制的字符集。例如,类 [^\W_] 匹配任何字母或数字,但不匹配下划线。
除 \, -、^(在开头)和终止 ] 之外的所有非字母数字字符在字符类中都不特殊,但即使它们被转义也不会造成任何伤害。模式终止符始终是特殊的,并且在表达式中使用时必须转义。
Perl 支持 POSIX 字符类的表示法。这使用在封闭方括号内的 [:
和 :]
之间封闭的名称。PCRE 也支持这种表示法。例如,[01[:alpha:]%]
匹配 "0"、"1"、任何字母字符或 "%"。支持的类名是
alnum | 字母和数字 |
alpha | 字母 |
ascii | 字符代码 0 - 127 |
blank | 仅空格或制表符 |
cntrl | 控制字符 |
digit | 十进制数字(与 \d 相同) |
graph | 打印字符,不包括空格 |
lower | 小写字母 |
print | 打印字符,包括空格 |
punct | 打印字符,不包括字母和数字 |
space | 空白(不完全与 \s 相同) |
upper | 大写字母 |
word | "单词" 字符(与 \w 相同) |
xdigit | 十六进制数字 |
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 字符属性结束范围将导致警告。
来自 PCRE 手册的深处 http://www.pcre.org/pcre.txt
\d 任何十进制数字
\D 任何不是十进制数字的字符
\h 任何水平空白字符
\H 任何不是水平空白字符的字符
\s 任何空白字符
\S 任何不是空白字符的字符
\v 任何垂直空白字符
\V 任何不是垂直空白字符的字符
\w 任何“单词”字符
\W 任何“非单词”字符
字符类的示例
<?php
$stringA = "1 起初神创造天地。";
$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("垂直制表符: %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:]]/', '', '我的年龄是 35 岁'); //string(10) "My age is "
$stringJ = preg_replace('/[[:^digit:]]/', '', '我的年龄是 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"
文档中写道
"字符类型 \d、\D、\s、\S、\w 和 \W 也可以出现在字符类中,并将它们匹配的字符添加到类中。"
它没有强调其他转义类型可能不会。我想要根据逗号 (",") 或换行符 "\n" 来拆分字符串。当我的输入流开始包含 "\r\n" 时,我决定将 "\n" 更改为 "\R"。不幸的是,我的测试字符串不包含大写字母 "R",否则我可能会更快地发现问题。我的 '/[\R,]/' 只会根据逗号和字母 "R" 进行拆分。
我的测试字符串...
"The Yum-Yum Company\r\n127 bernard street"
起作用的是:'/(?:\R|,)+/'
["The Yum-Yum Company","127 bernard street"]
鉴于字符类只匹配一个字符,我可以清楚地看到为什么我的预期会合理地落空,但希望这条评论可以为其他人节省时间。
我可能还会补充一点,这让我了解了 PCRE_EXTRA(修饰符 "X")的价值,我现在已经开始例行使用它了。
某些字符在自定义类中可能无法按预期工作。例如,MS 双引号在包含在类中时无法识别,但在其他情况下可以识别。
即
<?php
preg_match_all('/<a href=("|“)/')
?> 将匹配,但
<?php
preg_match_all('/<a href=["“]/')
?> 不会
当应用于 <a href=“path"> 时