字符组是正则表达式最基本的结构之一,字符组就是一组字符,在正则表达式中,它表示“在同一个位置可能出现的各种字符”。其写法是在一对方括号[.....]之间列出所有可能出现的字符。
字符可以分为很多类,比如数字、字母、符号等。
简单的字符组如:
[0123456789]、[987654321]、[012345abc6789]
字符范围表示法:
所谓范围表示法,就是用[x-y]的形式表示x到y整个范围内的字符,省去一一列出的麻烦,[0123456789]就可以用[0-9]表示。
范围表示法的范围是如何确定的:
在字符组中“-”表示的范围一般是根据字符对应的码值来确定的,码值小的字符在前,码值大的字符在后。在ASCLL编码中(十进制),字符0的码值是48,字符9的码值是57,所以[0-9]等价于[0123456789];而[9-0]则是错误的范围,因为9的码值大于0的码值,所以会报错。
[0-9]范围表示法的例子:
<?php
$str = '05816516551';
preg_match_all('/[0-9]/', $str, $res);
echo "<pre>";
print_r( $res );
运行结果:
Array
(
[0] => Array
(
[0] => 0
[1] => 5
[2] => 8
[3] => 1
[4] => 6
[5] => 5
[6] => 1
[7] => 6
[8] => 5
[9] => 5
[10] => 1
)
)
[9-0]错误范围表示法的示例
<?php
$str = '05816516551';
preg_match_all('/[9-0]/', $str, $res);
echo "<pre>";
print_r( $res );
运行结果:
Warning: preg_match_all(): Compilation failed: range out of order in character class at offset 3 in F:\phpStudy\WWW\1.php on line 4
如果你知道0-9的码值是48-57,a-z的码值是97-122,A-Z的码值是65-90,能不能用[0-z]同意表示数字字符、小写字母、大写字母呢?
答案是可以,但是不推荐这么做。
根据管理,字符组的范围表示法都表示一类字符(数字是一类)(字母是一类)。
[0-9]、[a-z]是很好理解的,但是[a-z]却很难理解,不熟悉ASCLL编码的人甚至不知道这个字符组还能匹配大写字母和不少标点符号。
奇怪的匹配示例:
<?php
preg_match_all('/[0-z]/', 'A', $res);
echo "<pre>";
print_r( $res );
Array
(
[0] => Array
(
[0] => A
)
)
可以看到[0-z]匹配大写字母A的时候居然也会成功匹配。
ASCLL编码表(片段)
码值 | 字符 | 码值 | 字符 | 码值 | 字符 | 码值 | 字符 | 码值 | 字符 |
48 | 0 | 63 | ? | 78 | N | 93 | ] | 108 | l |
49 | 1 | 64 | @ | 79 | O | 94 | ^ | 109 | m |
50 | 2 | 65 | A | 80 | P | 95 | _ | 110 | n |
51 | 3 | 66 | B | 81 | Q | 96 | ` | 111 | o |
52 | 4 | 67 | C | 82 | R | 97 | a | 112 | p |
53 | 5 | 68 | D | 83 | S | 98 | b | 113 | q |
54 | 6 | 69 | E | 84 | T | 99 | c | 114 | r |
55 | 7 | 70 | F | 85 | U | 100 | d | 115 | s |
56 | 8 | 71 | G | 86 | V | 101 | e | 116 | t |
57 | 9 | 72 | H | 87 | W | 102 | f | 117 | u |
58 | : | 73 | I | 88 | X | 103 | g | 118 | v |
59 | ; | 74 | J | 89 | Y | 104 | h | 119 | w |
60 | < | 75 | K | 90 | Z | 105 | i | 120 | x |
61 | = | 76 | L | 91 | [ | 106 | j | 121 | y |
62 | > | 77 | M | 92 | \ | 107 | k | 122 | z |