正则
正则:就是返回自己想要的把其他的都过滤掉,正则表达式主要用于:
- 正则匹配:根据正则表达式匹配相应的内容
- preg_match();第一次匹配成功后就会停止匹配,如果要实现全部结果的匹配,即搜索到subject结尾处,则需使用 preg_match_all() 函数
int preg_match( string pattern, string subject [, array matches ] )
- preg_match_all() int preg_match_all( string pattern, string subject, array matches [, int flags ] )
- preg_match();第一次匹配成功后就会停止匹配,如果要实现全部结果的匹配,即搜索到subject结尾处,则需使用 preg_match_all() 函数
- 正则替换:根据正则表达式匹配内容并替换
- preg_replace()
- 正则分割:根据正则表达式分割字符串
- array preg_split ( string
$pattern
, string$subject
[, int$limit
= -1 [, int$flags
= 0 ]] ) -
array split( string pattern, string string [, int limit] )一般推荐上面的替换函数但是此函数对大小写敏感,对大小写有严格要求的用它,注意
- array preg_split ( string
php正则效果小例子
正则表达式的作用:分割、查找、匹配。替换
原子:就是放到定界符中的字母数字等要匹配的字符如/love/ 里边的love就是原子在正则表达式中最少要有一个原子
自定义原子表 [ ] 里边的原子都是或者的关系 如上边的/love/是并且的意思即『先匹配l有的话在匹配l后是否有o前两个都有在匹配o后边是不是有v,然后lov都成立再见车lov后边是不是有e这4个有一个不成立都不会被匹配,』 so表示必须要匹配整体的love的字符;而/[love]/表示只要匹配的字符串里有单个的l,o,v或者e都会被匹配出来是或者的意思
分隔符:正斜线(/)、hash符号(#)、取反符号(~)
定界符:告诉PHP正则从哪里开始,从哪里结构,一般来说定界符为//,成对出现的。除了数字、字母、反斜线不可以作为定界符,其他都行。 如/love/
元字符:在定界符里的所有特殊字符都是元字符
. *+? ^ $ {n} {n,} {n,m} [] () [^] | [-]
模式中方括号外任何地方使用的 \ 一般用于转义字符 ^ 断言目标的开始位置(或在多行模式下是行首) $ 断言目标的结束位置(或在多行模式下是行尾) . 匹配除换行符外的任何字符(默认) [ 开始字符类定义 ] 结束字符类定义 | 开始一个可选分支 ( 子组的开始标记 ) 子组的结束标记 ? 作为量词,表示 0 次或 1 次匹配。位于量词后面用于改变量词的贪婪特性。 (查阅量词) * 量词,0 次或多次匹配 + 量词,1 次或多次匹配 { 自定义量词开始标记 } 自定义量词结束标记 模式中方括号内的部分称为“字符类”。 在一个字符类中仅有以下可用元字符: \ 转义字符 ^ 仅在作为第一个字符(方括号内)时,表明字符类取反 - 标记字符范围
限定符:
^ 如果在自定义原子表中的第一个位置使用代表排除,即使是排除也要匹配 '/a[^\w]c/'; 先匹配一个a然后匹配一个非a-z0-9A-Z_ 紧跟着匹配出一个c
* 代表前面的原子可以出现0次1次或多次。必须放在原子或原子表后面。/eg*/ 等价于匹配长度{0,}
+ 代表前面的原子可以出现1次或多次。/fo+/ 等价于匹配长度{1,}
? 代表前面的原子可以出现0次或1次 /Wil?/表示l必须出现0次到1次 等价于匹配长度{0,1}
{n} 代表前面的原子只能出现n次
{n,} 代表前面的原子最少出现n次,最多出现次数不限制
{n,m} 代表前面的原子最少出现n次,最多出现m次
要点:'*' '+' 和 '?' 只管它前面那个字符。如果想要管几个用()括起来如/W(il)?/表示li必须出现0次到1次
\d等价于[0-9]
\w等价于[A-Za-z_0-9]。
定位符:定位符也是元字符
^ 如果写在正则表达式的最前面表示必须以xx开始。如/^a/注意区别/[^a]/
$ 如果写在正则表达式的最后面表示必须以xx结尾。/[a-z][0-9]$/
. 代表任意一个字符(原子) 不能匹配\r\n
\b 匹配模式必须出现在目标字符串的开头或结尾的两个边界之一
\B 匹配对象必须位于目标字符串的开头和结尾两个边界之内,即匹配对象既不能作为目标字符串的开头,也不能作为目标字符串的结尾
"^abc$":就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配;
通用字符:通用字符也是元字符 指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式
通用字符作为原子
\d 任意一个数字 0~9
\D 任意一个非数字
\w 任意一个字符 a-z A-Z 0-9 _
\W 除了\w的东西
0-Z 只匹配数字和大写字母
0-z 匹配数字和大写字母小写字母
\s 空白 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符
\S 非空白
非打印字符
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
模式修正符:对正则解释进行修正用的单个符号。(写在定界符外面,写在右边) 注意:一个符号就是一个功能,可以组合起来使用
php支持: i m s x e(php7移除) A D S U X J u
i:正则表达式默认是区分大小写的。i的作用就是让正则表达式不区分大小写。
m:默认时候把所有的断行都当作一行来进行处理。把匹配字符串中的每个断行都当作新的一行 换行也能匹配。
s:修正正则表达式.,可以使其匹配\r\n 默认的时候.是不能匹配\r\n的
x:忽略正则中输入的空白,但如果目标字符串中再出现空白将无法匹配
U:正则表达式默认的时候是贪婪的(.*),如果要不让(.*)贪婪那么需要使用大写的U来取消贪婪,但是不建议用。(.*?)固定格式
例子: /^[a-z][0-9]$/i
#修正符:i 不区分大小写的匹配; #如:"/abc/i"可以与abc或aBC或ABc等匹配; #修正符:g表示全局匹配 #修正符:m 将字符串视为多行,不管是那行都能匹配; 例:#模式为:$mode="/abc/m"; #要匹配的字符串为:$str="bcefg5e\nabcdfe" #注意其中\n,换行了abc换到了下一行; #$str和$mode仍可以匹配,修正符m使得多行也可匹配; #修正符:s 将字符串视为单行,换行符作为普通字符; 例:#模式为:$mode="/pr.y/"; #要匹配字符串为:$str="pr\ny"; #两者不可匹配; . 是除了换行以外的字符可匹配; #修改下模式为:$mode="/pr.y/s"; #其中修正符s将\n视为普通字符,即不是换行; #最后两者可以匹配; #修正符:x 将模式中的空白忽略; $pattern = '/a c/x'; #这里的空白会被忽略 $string = 'a c'; if (preg_match($pattern, $string, $arr)) { echo "正则表达式<b>{$pattern}</b>和字符串<b>{$string}</b>匹配成功<br>"; print_r($arr); } else { echo "<font color='red'>正则表达式{$pattern}和字符串{$string}匹配失败</font>"; } #这次的匹配结果是失败的。因为我们使用模式修正符x取消了模式中的空格。注意:我们无法使用模式修正符取消\s表示的空白 #修正符:A 强制从目标字符串开头匹配; 例:#$mode="/abc/A"; #可以与$str="abcsdfi"匹配, #不可以与$str2="sdsdabc"匹配; #因为$str2不是以abc开头; #修正符:D 如果使用$限制结尾字符,则不允许结尾有换行; 例:#模式为:$mode="/abc$/"; #可以与最后有换行的$str="adshabc\n"匹配; #元子符$会忽略最后的换行\n; #如果模式为:$mode="/abc/D", #则不能与$str="adshabc\n"匹配, #修正符D限制其不可有换行;必需以abc结尾; #修正符:U 只匹配最近的一个字符串;不重复匹配; 例:#如模式为: $mode="/a.*c/"; $str="abcabbbcabbbbbc" ; preg_match($mode,$str,$content); echo $content[0]; //输出:abcabbbcabbbbbc; #如果$mode="/a.*c/";变成$mode="/a.*c/U"; # 则只匹配最近一个字符串,输出:abc; #修正符:e 配合函数preg_replace()使用, #可以把匹配来的字符串当作正则表达式执行;
注意:除了a-z A-Z 0-9 _这些原子外其他的字符在正则使用的时候加上\进行转义。让他变成普通的字符
基本语法
正则表达式的形式一般如下:
/love/
/fo+/: 先匹配f在匹配O由于+的作用f后面至少有一个O所以可以匹配到 “fool”, “fo”, 或者 “football”,foooo…..等
/eg*/: 含“*”元字符e后面连续出现零个或多个字母g的字符串相匹配,可以匹配到如 “easy”, “ego”, 或者 “egg”等在字母。
/Wil?/: 包含“?”元字符,表示可以与目标对象中的 “Win”, 或者 “Wilson”,等在字母i后面连续出现零个或一个字母l的字符串相匹配。
要点:'*' '+' 和 '?' 只管它前面那个字符。
除了元字符之外,用户还可以精确指定模式在匹配对象中出现的频率。例如,
/jim{2,6}/: 字符m可以在匹配对象中连续出现2-6次,因此,上述正则表达式可以同jimmy或jimmmmmy等字符串相匹配。
几个重要的元字符的使用方式。
\s:用于匹配单个空格符,包括tab键和换行符;空白如、\r \n \t
\S:用于匹配除单个空格(空白)符之外的所有字符;
\d:用于匹配从0到9的数字;
\D:任意一个非数字的包括空格等;
\w:用于匹配字母,数字或下划线字符;
\W:用于匹配所有与\w不匹配的字符;
. :用于匹配除换行符之外的所有字符。
(说明:我们可以把\s和\S以及\w和\W看作互为逆运算)
使用上述元字符例子。
/\s+/: 上述正则表达式可以用于匹配目标对象中的一个或多个空格字符。
/\d000/:如果我们手中有一份复杂的财务报表,那么我们可以通过上述正则表达式轻而易举的查找到所有总额达千元的款项。
定位符:用于规定匹配模式在目标对象中的出现位置。
/^hell/ ^必须以。。。开头 这里是必须以hell开头的字符串相匹配 如:“hell”, “hello” “hellhound”
/ar$/ $必须以。。结尾 这里是必须以ar结尾的字符串相匹配 如:“car”, “bar”或 “ar”
/\bbom/ : 以bom开始 以“\b”定位符开头,所以可以与目标对象中以 “bomb”, 或 “bom”开头的字符串相匹配。
/man\b/ :以bom结束 以“\b”定位符结尾,所以可以与目标对象中以 “human”, “woman”或 “man”结尾的字符串相匹配。
例子:
"^The":开头一定要有"The"字符串;
"of despair$":结尾一定要有"of despair" 的字符串;
"^abc$":就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配;
"notice":匹配包含notice的字符串;
指定某一个范围而不局限于具体的字符。例如:
/[A-Z]/ : 将会与从A到Z范围内任何一个大写字母相匹配。
/[a-z]/: 将会与从a到z范围内任何一个小写字母相匹配。
/[0-9]/: 将会与从0到9范围内任何一个数字相匹配。
/([a-z][A-Z][0-9])+/ : 将会与任何由小写字母+大写字母+数字组成的字符串,如 “aB0” 等相匹配
/([a-zA-Z0-9])+/ 可以匹配任何字母数字的字符串
如果我们希望在正则表达式中实现类似编程逻辑中的“或”运算,在多个不同的模式中任选一个进行匹配的话,可以使用管道符 “|”。例如:
/to|too|2/
上述正则表达式将会与目标对象中的 “to”, “too”, 或 “2” 相匹配
否定符 “[^]”。与我们前文所介绍的定位符 “^” 不同,否定符 “[^]”规定目标对象中不能存在模式中所规定的字符串。例如:
/[^A-C]/
上述字符串将会与目标对象中除A,B,和C之外的任何字符相匹配。一般来说,当“^”出现在 “[]”内时就被视做否定运算符;而当“^”位于“[]”之外,或没有“[]”时,则应当被视做定位符。
最后,当用户需要在正则表达式的模式中加入元字符,并查找其匹配对象时,可以使用转义符“\”。例如:
/Th\*/: 将会与目标对象中的“Th*”而非“The”等相匹配。
转义字符/
既然想.本身是不代表.的那么我要是想匹配.怎么办?那就要用到转义字符/
例如/.就匹配.
限定符:重复
如果说你想匹配连续5个数字怎么办,写五个/d太麻烦了吧,事实上我们肯定不会那么做?我们可以使用/d{5}.
常用的表重复的符号如下表:
字符 |
说明 |
* |
重复0到多次 |
+ |
重复1到多次 |
? |
重复零次或一次 |
{n} |
重复n次 |
{n, |
重复n到多次 |
{n,m} |
重复n到m次
|
懒惰限定符:?
如果有a.*b正则表达式,有字符accccbccb去匹配,达到的是accccbccb还是accccb呢?答案是前者,会找最长的。但是有时我们不希望这样,就可以使用懒惰限定符。比如上面的正则表达式可以这样a.*?b就可以解决问题了
常用的有
字符 |
说明 |
*? |
重复0到多次,但尽可能少的重复 代表(.*?) |
+? |
重复1到多次,但尽可能少的重复 |
?? |
重复0到一次,但尽可能少的重复 |
{n,m}? |
重复n到m次,但尽可能少的重复 |
{n}? |
重复n到多次,但尽可能少的重复 |
分支条件 |
如果你要表示固定电话或者手机号码,因为固定电话是0/d{3,4}-/d{7,8}而手机号码是/d{13}。怎么办,这是可以用分支0/d{3,4}-/d{7,8}|/d{13}。用|分开,表示要么匹配前面类型要么匹配后面类型。
分组()
上面说过重复一个字符0次、一次或多次,那么如何重复多个字符呢,就是我们要说的分组,例如要匹配一段IP地址(简单的IP匹配):(/d{1,3}/.){3}/d{1,3}.其中()括起来的部分重复3次。
零宽断言
负向零宽
(?:)(?=)(?!)(?<=)(?<!)(?i) 零宽断言
?
|
当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多的匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少的匹配“o”,得到结果 ['o', 'o', 'o', 'o']
|
.点
|
匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
|
(pattern)
|
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
|
(?:pattern)
|
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
|
find(?=pattern)
|
(零宽度正预测先行断言)正向预搜索(匹配find右边是pattern的find)非获取匹配,正向肯定预查,该匹配不需要获取供以后使用。例如判断Windows右侧是否出现pattern出现则匹配,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
|
find(?!pattern)
|
(零宽度负预测先行断言)正向预搜索(匹配find右边不是pattern的find)非获取匹配,正向否定预查,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。 \b((?!abc)\w)+\b:匹配由字母或数字或下划线或汉字组成的字串,但字串中不能出现abc |
(?<=pattern)find
|
(零宽度正回顾后发断言)反向预搜索(匹配find左边是pattern的find) 匹配pattern后面的位置 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
|
(?<!pattern)find
|
(零宽度负回顾后发断言) 反向预搜索(匹配find左边不是pattern的find) 匹配前面不是pattern的位置 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题
此处用或任意一项都不能超过2位,如“(?<!95|98|NT|20)Windows正确,“(?<!95|980|NT|20)Windows 报错,若是单独使用则无限制,如(?<!2000)Windows 正确匹配
|
反向引用:表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号
反向引用 |
说明 |
---|---|
\n |
对指定数字编号的分组进行反向引用 |
\g<name> |
对指定名字的命名分组进行反向引用 |
\k<name> |
|
\k'name' |
从一个简单例子说起
$subject="abcdebbcde";
$pattern="/([ab])\\1/"; // 注意php的\1前还需要加个\转义"\"
对于正则表达式“([ab])\1”,捕获组中的子表达式“[ab]”虽然可以匹配“a”或者“b”,但是捕获组一旦匹配成功,反向引用的内容也就确定了。如果捕获组匹配到“a”,那么反向引用也就只能匹配“a”,同理,如果捕获组匹配到的是“b”,那么反向引用也就只能匹配“b”。由于后面反向引用“\1”的限制,要求必须是两个相同的字符,在这里也就是“aa”或者“bb”才能匹配成功。
考察一下这个正则表达式的匹配过程,在位置0处,由“([ab])”匹配“a”成功,将捕获的内容保存在编号为1的组中,然后把控制权交给“\1”,由于此时捕获组已记录了捕获内容为“a”,“\1”也就确定只有匹配到“a”才能匹配成功,这里显然不满足,“\1”匹配失败,由于没有可供回溯的状态,整个表达式在位置0处匹配失败。
正则引擎向前传动,在位置5之前,“([ab])”一直匹配失败。传动到位置5处时,,“([ab])”匹配到“b”,匹配成功,将捕获的内容保存在编号为1的组中,然后把控制权交给“\1”,由于此时捕获组已记录了捕获内容为“b”,“\1”也就确定只有匹配到“b”才能匹配成功,满足条件,“\1”匹配成功,整个表达式匹配成功,匹配结果为“bb”,匹配开始位置为5,结束位置为7。
扩展一下,正则表达式“([a-z])\1{2}”也就表达连续三个相同的小写字母。
$subject="abc 123abcd"; $pattern="/(abc)(\s)(\d)+?\\1/";//\1就是第一个()组匹配到的内容 注意需要将\转义下 $a=preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE); var_export($matches);//匹配到abc 123abc
更多反向引用实例
$pattern="/(\w)/"; $a=preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE); var_export($matches); #['A','A','A','B','B','C','C','A','A','A','A','D','D','E','6','6','6','F','F'; $pattern="/(\w)\\1/"; # array ( 'AA', 'BB', 'CC','AA', 'AA', 'DD', '66','FF',) $pattern="/(\w)\\1*/"; #[ 'AAA', 'BB', 'CC', 'AAAA', 'DD', 'E', '666', 'FF' ] $pattern="/(\w)+/"; #[ 'AAA', 'BB', 'CC', 'AAAA', 'DD', '666', 'FF' ] $pattern="/(\w)(\d)/"; #[ 'E6', '66' ] $pattern="/(\w)(\d)\\1/"; #array ( '666') $pattern="/(\w)(\d)\\1*/"; #[ 'E6', '66' ] $pattern="/(\w)(\d)\\1+/"; #[ '666' ] $pattern="/(\w)(\d)\\1\\2*/"; #[ 'E666' ] $pattern="/(\w)(\d)\\1\\2+/"; #[ 'E666' ]
$subject="aaa bbbb ffffff 999999999";
$pattern="/(\w)((?=\\1\\1\\1)(\\1))+/"; $a=preg_match_all($pattern, $subject, $matches); var_export($matches); # [ 'bb', 'ffff', '9999999'] # (?=exp)非获取匹配的正向肯定预查 匹配\1\1\1左边的\w 而\1 又是第一个\w \1\1\1可知至少三个相同的\w字符 后面的(\\1)+可知至少一个 # (\w)((?=\\1\\1\\1) 三个相同的\w字左边还有一个相同的\为字符 即符四个相同的\w字符 #
独立表达式 (?>pattern) 也叫固化分组?:在固化分组中,永远不会"交还"已经匹配的任何内容。固化分组还有一个重要的用途,尤其是能提高匹配的效率 成功匹配后,回溯时不会考虑这个匹配的字符
$pattern="\.(\d\d(?>[1-9]?))\d+"
一般匹配步骤:
$subject=123.456;
$pattern="/\.(\d\d[1-9]?)\d+/"
【\.】匹配".",匹配成功,把控制权给下一个【\d】,
【\d】匹配“4”成功,把控制权给第二个【\d】,
这个【\d】匹配“5”成功,然后,把控制权给了【[1-9]?】,
由于量词是【?(0次或者1次)】,正则表达式遵循“量词优先匹配”,而且,此处是【?】,还会留下一个回溯点。然后匹配"6"成功,
然后把控制权给【\d+】,【\d+】发现后面没字符了,最遵循“后进先出”规则,回到上一个回溯点,进行匹配,
这时,【[1-9]?】会交还出其匹配的字符“6”,【[1-9]?】匹配“6”成功。匹配完成了。
大家发现【(\d\d[1-9]?)】匹配的结果确是"45",并不是我们想要的“456”,“6”被【\d+】匹配去了。那么,我们该如何办呢?
(/ab{1,3}c/"相对于"abbc"有回溯,而对于"abbbc"则无回溯 我的理解是在贪婪匹配成功后下一个规则不匹配则会在还是满足前一个规则的情况下进行回溯再次匹配下一个规则)
条件表达式(?(Expression)yes|no)它是“(?(?=Expression)yes|no)”的简写形式,相当于三元运算符
如果“Expression”与可能出现的命名捕获组的组名相同,为避免混淆,可以采用“(?(?=Expression)yes|no)”方式显示声明“Expression”为子表达式,而不是捕获组名
表达式 |
条件特点 |
条件说明 |
---|---|---|
(?(1)yes|no) |
条件为数字 |
分组1如果有捕获,则进行 yes 部分匹配,否则 no 部分 |
(?(?=a)yes|no) |
条件为预搜索 |
如果当前位置右侧是 a,则进行匹配 yes,否则匹配 no |
(?(xxx)yes|no) |
不与分组命名吻合 |
如果不与任何分组命名吻合,则视为 (?=xxx)相同 |
(?(name)yes|no) |
与分组命名吻合 |
如果与某分组命名吻合,则视为判断该分组是否进行捕获 |
(?(xxoo)yes) | 只有一个条件表达式 | 当只有一个条件时那么yes只能在条件成立下匹配 |
(?(xxoo)yes|no1|no2), |
条件表达式大于2个 | 以第一个|为准 成功匹配yes 不成功匹配no1|no2 |
(?(?=a)\w{2}|\w) 当前位置右侧如果是字符“a” ,则匹配两个“\w”,否则匹配一个“\w”
$str="a+(b*(c+d))/e+f-(g/(h-i))*j";
$pattern="/\(((?<Open>\()|(?<-Open>\))|[^()]+)*(?(Open)(?!))\)/";
$pattern="/ \( #先匹配普通的开括号( ( (?<Open>\() #命名捕获组,遇到开括弧(则’Open’计数加1 | (?<-Open>\)) #狭义平衡组,遇到闭括弧)则’Open’计数减1 每匹配到一个“)”,就出栈最近入栈的Open捕获组,$matchs计数减1 | [^()]+ #非括弧的其它任意字符 )* (?(Open)(?!)) #判断是否还有’Open’,有则说明不配对,什么都不匹配 \) #匹配普通闭括号 /";
后面的(?(Open)(?!))用来保证堆栈中Open捕获组计数是否为0,也就是“(”和“)”是配对出现的 5. 最后的“)”,作为匹配的结束
需要对“(?!)”进行一下说明,它属于顺序否定环视,完整的语法是“(?!Expression)”。由于这里的“Expression”不存在,表示这里不是一个位置,所以试图尝试匹配总是失败的,作用就是在Open不配对出现时,报告匹配失败
平衡组用于匹配嵌套层次结构,常用于匹配HTML标签(当HTML内容不规范,起始标签和结束标签数量不同时,匹配出正确配对的标签),在此把表达式统一以\w
为例。
(?'group'\w)
捕获的分组(\w
匹配到的内容)命名为group
,并压入堆栈(?'-group'\w)
捕获分组(\w
匹配到的内容)后,弹出group
分组栈的栈顶内容(最后压入的捕获内容),堆栈本来为空,则本分组的匹配失败(?(group)yes|no)
如果group
栈非空匹配表达式yes
,否则匹配表达式no
(?!)
零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
平衡组分狭义平衡组与广义平衡组
狭义平衡组指.NET中定义的(?<Close-Open>Expression)
广义平衡组并不是固定的语法规则,而是几种语法规则的综合运用,我们平时所说的平衡组通常指的是广义平衡组。本文中如无特殊说明,平衡组这种简写指的是广义平衡组
平衡组通常是由量词,分支结构,命名捕获组,狭义平衡组,条件判断结构组成的,量词和分支结构这里不做介绍,这里只对命名捕获组,狭义平衡组和条件判断结构做下说明
递归表达式 (?R) 针对表达式 反向引用针对匹配内容
格式 |
说明 |
---|---|
(?R) |
对整个表达式的递归引用。 |
(?R1),(?R2) |
对指定分组的递归引用。 |
(?1),(?2) |
|
(?R<named>) |
对指定命名分组的递归引用。 |
(?R'named') |
(\w)(?1) 等效于 (\w)(\w) # (?1)代表引用第一个分组即\w (?2)代表引用第二个分组即\d (?1)(\w(?2))(\d)=>(?1)(\w(\d))(\d)=>(\w(\d))(\w(\d))(\d) #被引用的表达式又包含自身,则形成了递归引用 (\w(?1)?)=>(\w(\w(?1)?)?)=>(\w(\w(\w(?1)?)?)?)=>...=>(\w+)
表达式替换语法
$1 ~ $999 代表某个捕获组捕获到的内容。如果捕获组编号大于表达式中的最大捕获组编号,那么 DEELX 会减少数字个数,以使捕获组编号小于或等于最大编号;而把剩余的数字看作字符串常量。 举例: 当前最大捕获组编号为 20,那么,指定替换为 "$999" 将被看作 "$9" + "99";指定替换为 "$15" 将代表第 15 个捕获组。如果本来就是想把 "5" 当成字符串常量时("$1" + "5"),可以使用 $0015 表示,DEELX 最多识别 3 位 10 进制数字。 -------------------------------------------------------------------------------- ${name} 代表指定命名分组捕获到的内容。 -------------------------------------------------------------------------------- $$ 表示一个 $ 符号。 -------------------------------------------------------------------------------- $& 代表每次匹配到内容。 -------------------------------------------------------------------------------- $` 代表原字符串中,匹配到的内容之前的字符串。$` 中`符号就是键盘左上角"~"下边的那个符号。 -------------------------------------------------------------------------------- $' 代表原字符串中,匹配到的内容之后的字符串。$' 中 ' 符号就是单引号。 -------------------------------------------------------------------------------- $+ 代表所有“有捕获”的分组中,编号最大的那个分组。 举例:"aaa(b+)|ccc(b+)" 在匹配 "aaabbb" 时,虽然最大分组是第2个分组,但最大“有捕获”的是第1个分组,此时的 $+ 代表 $1 。 -------------------------------------------------------------------------------- $_代表被替换的 整个字符串。"_" 是下划线。
3、使用实例
①PHP中可以使用ereg()函数进行模式匹配操作。ereg()函数的使用格式如下:
ereg($pattern, $string,$match) 匹配成功返回1 使用 Perl 兼容正则表达式语法的 preg_match() 函数通常是比 ereg() 更快的替代方案
在PHP5.3里边ereg家族系列被preg系列代替了 7.0已被移除 所以是个过时的函数
其中,pattern代表正则表达式的模式,而string则是执行查找替换操作的目标对象。同样是验证邮件地址,使用PHP编写的程序代码如下:
if (ereg(“^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+”,$email)){ echo “Your email address is correct!”; }else{ echo “Please try again!”; }
②javascript 1.2中带有一个功能强大的RegExp()对象,可以用来进行正则表达式的匹配操作。其中的test()方法可以检验目标对象中是否包含匹配模式,并相应的返回true或false。
我们可以使用javascript编写以下脚本,验证用户输入的邮件地址的有效性。
<html> <head> <script language=\"javascript1.2\"> <!-- start hiding function verifyAddress(obj){ var email = obj.email.value; var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/; flag = pattern.test(email); if(flag){ alert(“Your email address is correct!”); return true; }else{ alert(“Please try again!”); return false; } } // stop hiding --> </script> </head> <body> <form onSubmit=\"return verifyAddress(this);\"> <input name=\"email\" type=\"text\"> <input type=\"submit\"> </form> </body> </html>
这里是一些例子:
"a(bc)*": 匹配 a 后面跟0个或者一个"bc";0个或者多个吧?
"a(bc){1,5}": 一个到5个 "bc";
还有一个字符 '|',相当于OR操作:
"hi|hello": 匹配含有"hi" 或者 "hello" 的 字符串;
"(b|cd)ef": 匹配含有 "bef" 或者 "cdef"的字符串;
"(a|b)*c": 匹配含有这样多个(包括0个)a或b,后面跟一个c的字符串;
一个点('.')可以代表所有的单一字符,不包括"\n"
如果,要匹配包括"\n"在内的所有单个字符,怎么办? 用'[\n.]'这种模式。
"a.[0-9]": 一个a加一个字符再加一个0到9的数字;
"^.{3}$": 三个任意字符结尾。
中括号括住的内容只匹配一个单一的字符
"[ab]": 匹配单个的 a 或者 b ( 和 "a│b" 一样);
"[a-d]": 匹配'a' 到'd'的单个字符 (和"a│b│c│d" 还有 "[abcd]"效果一样);
一般我们都用[a-zA-Z]来指定字符为一个大小写英文:
"^[a-zA-Z]": 匹配以大小写字母开头的字符串;
"[0-9]%": 匹配含有 形如 x% 的字符串;
",[a-zA-Z0-9]$": 匹配以逗号再加一个数字或字母结尾的字符串;
你也可以把你不想要得字符列在中括号里,你只需要在总括号里面使用'^' 作为开头
"%[^a-zA-Z]%" 匹配含有两个百分号里面有一个非字母的字符串。
要点:^用在中括号开头的时候,就表示排除括号里的字符。
为了PHP能够解释,你必须在这些字符面前后加'',并且将一些字符转义。
注意:在中括号里面,所有的特殊字符,包括(''),都将失去他们的特殊性质
"[*\+?{}.]" 匹配含有这些字符的字符串:
"如果列表里含有']',最好把它作为列表里的第一个字符(可能跟在'^'后面)。如果含有'-',最好把它放在最前面或者最后面, or 或者一个范围的第二个结束点[a-d-0-9]中间的‘-’将有效。
"p{1,5}"将匹配 "pvpppppp"中的前五个p
正则表达式主要用于:
- 正则匹配:根据正则表达式匹配相应的内容
- 正则替换:根据正则表达式匹配内容并替换
- 正则分割:根据正则表达式分割字符串
① int preg_match ( string $pattern="正则匹配模式"
, string $subject="要匹配的字符串"
[, array &$matches
[, int $flags
= 0 [, int $offset
= 0 ]]] ) 执行匹配正则表达式
$matches:储存匹配结果的数组。 $matches[0]将包含整个模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推
$flags:如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。 注意:这会改变填充到matches
参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject
中的偏移量
$offset:可选参数 offset
用于 指定从目标字符串的某个字节位置开始搜索(单位是字节不是字符)如utf8 一个汉字是3字节空格一个字节
preg_match:返回匹配次数;值永远是0或者1 应为此函数将在第一次匹配成功后就不会在往后匹配了,如果想要配配所有的需要用preg_match_all函数
如果你想要检查缪个字符串是否包含另一个字符串不要用preg_match使用strpos()效率更高
$subject = "啊大萨 达萨达达萨达"; $pattern = '/达萨达/'; $a = preg_match_all($pattern, $subject, $ , PREG_OFFSET_CAPTURE, 2); echo '<pre>'; print_r($matches); var_dump($a);
输出:
Array ( [0] => Array ( [0] => 达萨达 [1] => 11 ) ) int(1)
说明
$pattern
,string $subject
[,array &$matches
[, int $flags
= PREG_PATTERN_ORDER
[, int$offset
= 0 ]]] ) 执行一个全局正则表达式匹配搜索subject
中所有匹配pattern
给定正则表达式 的匹配结果并且将它们以flag
指定顺序输出到matches
中.
在第一个匹配找到后, 子序列继续从最后一次匹配位置搜索.
$subject = "啊大萨 达萨达达萨达"; $pattern = '/达萨达/'; $a = preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 2); echo '<pre>'; print_r($matches); var_dump($a);
输出
Array ( [0] => Array ( [0] => Array ( [0] => 达萨达 [1] => 11 //$pattern 从$subject字符串中第11个字节开始匹配的 ) [1] => Array ( [0] => 达萨达 [1] => 20 ) ) )
③ preg_filter — 执行一个正则表达式搜索和替换
④preg_replace_callback_array — Perform a regular expression search and replace using callbacks
$subject = array('1', 'a', '2', 'b', '3', 'A', 'B', '4'); $pattern = array('/\d/', '/[a-z]/', '/[1a]/'); $replace = array('A:$0', 'B:$0', 'C:$0'); #拿pattern里的每一个模式依次去匹配subject里的每一个元素,匹配到了就用与pattern对应的那个replace对换 preg_filter($pattern, $replace, $subject); Array( [0] => A:C:1 $pattern[0]匹配$subject[0] A:1 $pattern[1]匹配$subject[0] 未匹配上 $pattern[2]匹配$subject[0] A:C:1 [1] => B:C:a [2] => A:2 [3] => B:b [4] => A:3 [7] => A:4 ) preg_replace($pattern, $replace, $subject); Array( [0] => A:C:1 [1] => B:C:a [2] => A:2 [3] => B:b [4] => A:3 [5] => A [6] => B [7] => A:4 )
一般 若匹配模式和替换内容这两项都是数组的话它们应该相对应,如果replacement中的元素比pattern中的少, 多出来的pattern使用空字符串进行替换. pattern就像个扫描器,扫到匹配的就用于之对应的replace替换 对于上例替换过程如下 /\d/扫描subject里的1,匹配了,匹配内容为0(也就是1)就把1替换为A:1 然后用/[a-z]/扫描A:1不匹配,就不替换,继续用[1a]扫描A:1,匹配内容为1(也就是$0),就把A:1中1换为C:1 第一项最终被替换为A:C:1 简化过程 1->A:1->A:C:1 a->B:a->B:C:a 2->A:2 b->B:b A(没有符合匹配的就不替换了) B(同上) 4->A:4 总结一点,拿pattern里的每一个模式依次去匹配subject里的每一个元素,匹配到了就用与pattern对应的那个replace对换,如上例,可能不止一次替换
⑤ preg_grep — 返回匹配模式的数组条目
$array = array(1, 2, 3.4, 53, 7.9); // 返回所有包含浮点数的元素 $fl_array = preg_grep("/^(\d+)?\.\d+$/", $array); print_r($fl_array); 结果 Array( [2] => 3.4 [4] => 7.9 )
⑥ preg_last_error — 返回最后一个PCRE正则执行产生的错误代码
⑦preg_quote — 转义正则表达式特殊字符
#正则表达式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - $keywords = '$40 for a g3/400'; #注意上面的特殊符号没有包含/所以我们需要第二个参数加上/否则不会转义/(通常都是正则的分隔符/^[\d]$/ 中的/) $keywords = preg_quote($keywords, '/');#第二个参数未设置时结果是\$40 for a g3/400 结果 \$40 for a g3\/400
⑧preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换
⑨preg_replace — 执行一个正则表达式的搜索和替换
⑩preg_split — 通过一个正则表达式分隔字符串
(?P<name>)是命名子组,可以接受(?<name>), (?'name') 以及(?P<name>)语法.
例如
//命名一个子组 并且将[^'\"\<\>]+?匹配的内容存入其中
preg_match_all('/\bhref=['\"](?P<match>[^'\"\<\>]+?)['\"]/i',$html(拉取的html源码),$match_urls,PREG_SET_ORDER) var_dump($match_urls); 返回(这里是json) [{ "0":"href="http://news.163.com/special/0001386F/rank_whole.html"", "1":"http://news.163.com/special/0001386F/rank_whole.html", "match":"http://news.163.com/special/0001386F/rank_whole.html" },{ "0":"href="http://home.163.com/19/0423/07/EDE97EQQ001081EI.html"", "1":"http://home.163.com/19/0423/07/EDE97EQQ001081EI.html", "match":"http://home.163.com/19/0423/07/EDE97EQQ001081EI.html" }]
/123/等价于/[1][2][3]/
()内的内容表示的是一个子表达式,()本身不匹配任何东西,也不限制匹配任何东西,只是把括号内的内容作为同一个表达式来处理,例如(ab){1,3},就表示ab一起连续出现最少1次,最多3次。如果没有括号的话,ab{1,3},就表示a,后面紧跟的b出现最少1次,最多3次
[]表示匹配的字符在[]中,并且只能出现一次,并且特殊字符写在[]会被当成普通字符来匹配。例如[(a)],会匹配(、a、)、这三个字符
正则其实也可爱,削尖头来美刀揣; (指开始符号^和结尾符号$) 特殊符号认不了,弄个倒杠来转义; (指\. \*等特殊符号) 倒杠后面跟小乌w, 数字字母下划线; (\w跟数字字母下划线) 倒杠后面跟小d, 只有数字来表示; (\d跟数字) 倒杠后面跟小a, 报警符号嘀一声; 倒杠后面跟小b, 单词分界或退格; 单词和空格间的位置 “er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 倒杠后面跟小t, 制表符号很明了; 倒杠后面跟小r, 回车符号知道了; \r:回车\n:换行 倒杠后面跟小s, 空格符号很重要; \s是指空白,包括空格、换行、tab缩进等所有的空白 小写跟罢跟大写,多得实在不得了; 倒杠后面跟大乌W, 字母数字靠边站; 非单词字母下划线的字符 等价于“[^A-Za-z0-9_]” 倒杠后面跟大使S, 空白也就靠边站; 倒杠后面跟大D, 数字从此靠边站; 倒框后面跟大B, 不含开头和结尾; 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 单个字符要重复,三个符号来帮忙; (* + ?) 0 星加1 到无穷,问号只管0 和1; (*表0-n;+表1-n;?表0-1次重复) 花括号里学问多,重复操作能力强; ({n} {n,} {n,m})可完全代替(* + ?) 除(?:)(?=)(?!)(?<=)(?<!)(?i)(*?)(+?) 若要重复字符串,园括把它括起来; ((abc){3} 表示字符串“abc”重复3次 ) 特殊集合自定义,中括号来帮你忙; 转义符号行不通,一个一个来排队; ??? 实在多得排不下,横杠请来帮个忙; ([1-5]) 尖头放进中括号,反义定义威力大; ([^a]指除“a”外的任意字符 ) 1竖作用可不小,两边正则互替换; (键盘上与“\”是同一个键) 1竖能用很多次,复杂定义很方便; 圆括号,用途多; 反向引用指定组,数字排符对应它; (“\b(\w+)\b\s+\1\b”中的数字“1”引用前面的“(\w+)”) 支持组名自定义,问号加上尖括号; (“(?<Word>\w+)”中把“\w+”定义为组,组名为“Word”) 园括号,用途多,位置指定全靠它; 问号等号字符串,定位字符串前面; (“\b\w+(?=ing\b)”定位“ing”前面的字符串) 若要定位串后面,中间插个小于号; (“(?<=\bsub)\w+\b”定位“sub”后面的字符串) 问号加个惊叹号,后面跟串字符串; PHPer都知道, !是取反的意思; 后面不跟这一串,统统符合来报到; (“\w*d(?!og)\w*”,“dog”不符合,“do”符合) 问号小于惊叹号,后面跟串字符串; 前面不放这一串,统统符合来报到; 点号星号很贪婪,加个问号不贪婪; 加号问号有保底,至少重复一次多; 两个问号老规矩,0次1次团团转; 花括号后跟个?,贪婪变成不贪婪; 还有很多装不下,等着以后来增加。
https://imweb.io/topic/56e804ef1a5f05dc50643106
一些常用的正则表达式
正则匹配中文汉字
正则匹配中文汉字根据页面编码不同而略有区别:
- GBK/GB2312编码:[x80-xff]+ 或 [xa1-xff]+
- UTF-8编码:[x{4e00}-x{9fa5}]+/u
utf8汉字的编码范围:0x4e00-0x9fa5 utf-8要使用 u模式修正符 使模式字符串被当成utf-8 /[\x{4e00}-\x{9fa5}]+/u
GBK/GB2312编码范围:0xb0-0xf7 ,0xa1-0xfe ANSI(gb2312)环境下,要使用chr将Ascii码转换为字符
<("[^"]*"|'[^']*'|[^'">])*> 匹配html标签
"^\d+$" //非负整数(正整数
+ 0)
"^[0-9]*[1-9][0-9]*$" //正整数
"^((-\d+)|(0+))$" //非正整数(负整数
+ 0)
"^-[0-9]*[1-9][0-9]*$" //负整数
"^-?\d+$" //整数
"^\d+(\.\d+)?$" //非负浮点数(正浮点数
+ 0)
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$" //正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$" //非正浮点数(负浮点数
+ 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负浮点数
"^(-?\d+)(\.\d+)?$" //浮点数
"^[A-Za-z]+$" //由26个英文字母组成的字符串
"^[A-Z]+$" //由26个英文字母的大写组成的字符串
"^[a-z]+$" //由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$" //由数字和26个英文字母组成的字符串
"^\w+$" //由数字、26个英文字母或者下划线组成的字符串
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$" //url
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/
// 年-月-日
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/
// 月/日/年
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$"
//Emil
"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?"
//电话号码
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$"
//IP地址
匹配中文字符:
[\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[^\x00-\xff]
匹配空行:\n[\s|
]*\r
匹配HTML标记:/<(.*)>.*<\/\1>|<(.*)
\/>/
匹配首尾空格:(^\s*)|(\s*$)
匹配Email:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
email地址 : "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"
匹配email: ^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$
匹配网址URL的正则表达式:^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?
匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$
^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$ 匹配货币数量
常用正则:
1、匹配中文:[\u4e00-\u9fa5] 2、英文字母:[a-zA-Z] 3、数字:[0-9] 4、匹配中文,英文字母和数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$ 同时判断输入长度: [\u4e00-\u9fa5_a-zA-Z0-9_]{4,10}
array('web_name','/^[A-Za-z0-9\x{4e00}-\x{9fa5}]{2,20}$/u','网站名由不是汉字字母数字组成',1,'regex',3),
5、 (?!_) 不能以_开头 (?!.*?_$) 不能以_结尾 [a-zA-Z0-9_\u4e00-\u9fa5]+ 至少一个汉字、数字、字母、下划线 $ 与字符串结束的地方匹配 6、只含有汉字、数字、字母、下划线,下划线位置不限: ^[a-zA-Z0-9_\u4e00-\u9fa5]+$ 7、由数字、26个英文字母或者下划线组成的字符串 ^\w+$ 8、2~4个汉字 "^[\u4E00-\u9FA5]{2,4}$"; 9、最长不得超过7个汉字,或14个字节(数字,字母和下划线)正则表达式 ^[\u4e00-\u9fa5]{1,7}$|^[\dA-Za-z_]{1,14}$ 10、匹配双字节字符(包括汉字在内):[^x00-xff] 评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 11、匹配空白行的正则表达式:ns*r 评注:可以用来删除空白行 12、匹配HTML标记的正则表达式:<(S*?)[^>]*>.*?|<.*? /> 评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力 13、匹配首尾空白字符的正则表达式:^s*|s*$ 评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式 14、匹配Email地址的正则表达式:^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$ 评注:表单验证时很实用 15、手机号:^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$ 16、身份证:(^\d{15}$)|(^\d{17}([0-9]|X|x)$) 17、匹配网址URL的正则表达式:[a-zA-z]+://[^s]* 评注:网上流传的版本功能很有限,上面这个基本可以满足需求 18、匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 评注:表单验证时很实用 19、匹配国内电话号码:d{3}-d{8}|d{4}-d{7} 评注:匹配形式如 0511-4405222 或 021-87888822 20、匹配腾讯QQ号:[1-9][0-9]{4,} 评注:腾讯QQ号从10000开始 21、匹配中国邮政编码:[1-9]d{5}(?!d) 评注:中国邮政编码为6位数字 22、匹配身份证:d{15}|d{18} 评注:中国的身份证为15位或18位 23、匹配ip地址:d+.d+.d+.d+ 评注:提取ip地址时有用 24、匹配特定数字: ^[1-9]d*$ //匹配正整数 ^-[1-9]d*$ //匹配负整数 ^-?[1-9]d*$ //匹配整数 ^[1-9]d*|0$ //匹配非负整数(正整数 + 0) ^-[1-9]d*|0$ //匹配非正整数(负整数 + 0) ^[1-9]d*.d*|0.d*[1-9]d*$ //匹配正浮点数 ^-([1-9]d*.d*|0.d*[1-9]d*)$ //匹配负浮点数 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$ //匹配浮点数 ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$ //匹配非负浮点数(正浮点数 + 0) ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$ //匹配非正浮点数(负浮点数 + 0) 评注:处理大量数据时有用,具体应用时注意修正 25、匹配特定字符串: ^[A-Za-z]+$ //匹配由26个英文字母组成的字符串 ^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串 ^[a-z]+$ //匹配由26个英文字母的小写组成的字符串 ^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串 ^w+$ //匹配由数字、26个英文字母或者下划线组成的字符串 26、 在使用RegularExpressionValidator验证控件时的验证功能及其验证表达式介绍如下: 只能输入数字:“^[0-9]*$” 只能输入n位的数字:“^d{n}$” 只能输入至少n位数字:“^d{n,}$” 只能输入m-n位的数字:“^d{m,n}$” 只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$” 只能输入有两位小数的正实数:“^[0-9]+(.[0-9]{2})?$” 只能输入有1-3位小数的正实数:“^[0-9]+(.[0-9]{1,3})?$” 只能输入非零的正整数:“^+?[1-9][0-9]*$” 只能输入非零的负整数:“^-[1-9][0-9]*$” 只能输入长度为3的字符:“^.{3}$” 只能输入由26个英文字母组成的字符串:“^[A-Za-z]+$” 只能输入由26个大写英文字母组成的字符串:“^[A-Z]+$” 只能输入由26个小写英文字母组成的字符串:“^[a-z]+$” 只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+$” 只能输入由数字、26个英文字母或者下划线组成的字符串:“^w+$” 验证用户密码:“^[a-zA-Z]w{5,17}$”正确格式为:以字母开头,长度在6-18之间, 只能包含字符、数字和下划线。 验证是否含有^%&',;=?$"等字符:“[^%&',;=?$x22]+” 只能输入汉字:“^[u4e00-u9fa5],{0,}$” 验证Email地址:“^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$” 验证InternetURL:“^http://([w-]+.)+[w-]+(/[w-./?%&=]*)?$” 验证身份证号(15位或18位数字):“^d{15}|d{}18$” 验证一年的12个月:“^(0?[1-9]|1[0-2])$”正确格式为:“01”-“09”和“1”“12” 验证一个月的31天:“^((0?[1-9])|((1|2)[0-9])|30|31)$” 正确格式为:“01”“09”和“1”“31”。 匹配中文字符的正则表达式: [u4e00-u9fa5] 匹配双字节字符(包括汉字在内):[^x00-xff] 匹配空行的正则表达式:n[s| ]*r 匹配HTML标记的正则表达式:/<(.*)>.*|<(.*) />/ 匹配首尾空格的正则表达式:(^s*)|(s*$) 匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)* 匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?
正则匹配中文汉字
正则匹配中文汉字根据页面编码不同而略有区别:
- GBK/GB2312编码:[x80-xff]+ 或 [xa1-xff]+
- UTF-8编码:[x{4e00}-x{9fa5}]+/u
utf8汉字的编码范围:0x4e00-0x9fa5 utf-8要使用 u模式修正符 使模式字符串被当成utf-8 /[\x{4e00}-\x{9fa5}]+/u
GBK/GB2312编码范围:0xb0-0xf7 ,0xa1-0xfe ANSI(gb2312)环境下,要使用chr将Ascii码转换为字符
反向引用 |
说明 |
---|---|
\nnn |
对指定编号的分组进行反向引用 |
\g<name> |
对指定名字的命名分组进行反向引用 |
\k<name> |
|
\k'name' |
(\w)(?1) |
(\w)(\w) |