正则表达式介绍
正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。到目前为止,我们前面所用过的精确(文本)匹配也是一种正则表达式。
在PHP中,正则表达式一般是由正规字符和一些特殊字符(类似于通配符)联合构成的一个文本模式的程序性描述。
正则表达式的三个作用
1.匹配,也常常用于从字符串中解析取信息。
2.新文本匹配替代文本。
3.讲一个字符串拆分为一组更小的信息块。
与Perl语言兼容的正则表达式处理函数
函数名 | 功能 |
preg_match() | 进行正则表达式匹配 |
preg_match_all() | 进行全局正则表达式匹配 |
preg_replace() | 进行正则表达式的搜索和替换 |
preg_split() | 用正则表达式分割字符串 |
preg_grep() | 返回与模式匹配的数组单元 |
preg_replace_callback() | 用回调函数执行正则表达式的搜索和替换 |
正则表达式的语法规则
正则表达式作为一个匹配的模版,是由原子(普通字符,例如字符a到z)、特殊字符(元字符,例如*、+和?等)、以及模式修正符三部分组成的文字模式。
一个最简单正则表达式至少包含一个原子。
将下面的正则表达式拆分如下:
'/<a.*?(?:|\\t|\\r|\\n)?href=[\"]?(.+?)[\"]?(?:(?:|\\t|\\r|\\n)+.*?)?>(.+?)<\/a.*?>/sim'
定界符:两个斜线”/”。
原子用到了< a href = ‘ “ / >等普通字符和\t \r \n等转义字符
元字符使用了 [] () | . ? * + 等具有特殊含义的字符
用到了模式修正符是在定界符最后一个斜线之后的三个字符: s i m
定界符
在程序语言中,使用与Perl兼容的正则表达式,通常都需要将模式表达式放入定界符之间,如“/”。
作为定界符常使用反斜线“/”,如“/apple/”。用户只要把需要匹配的模式内容放入定界符之间即可。作为定界的字符也不仅仅局限于“/”。除了字母、数字和斜线“\”以外的任何字符都可以作为定界符,像 ‘#’、’|’、’!’ 等都可以的。
- /</\w+>/ --使用反斜线作为定界符合法
- |(\d{3})-\d+|Sm --使用竖线”|”作为定界符合法
- !^(?i)php[34]! --使用竖线”!”作为定界符合法
- {^\s+(\s+)?$} --使用竖线”}”作为定界符合法
- /href=‘(.*)’ --非法定界符,缺少结束定界符
- 1-\d3-\d3-\d4| --非法定界符,缺少其实定界符
原子
原子是正则表达式的最基本的组成单元,而且在每个模式中最少要少包含一个原子。原子是由所有那些未显示指定为元字符的打印和非打印字符组成,具体分为5类。
- 普通字符作为原子: 如 az、AZ、0~9 等
- 一些特殊字符和转义后元字符作为原子:
所有标点符号,但语句特殊意义的符号需要转义后才可作为原子,如:\” \’ * + ? . 等 - 一些非打印字符作为原子: 如:\f \n \r \t \v \cx
- 使用“通用字符类型”作为原子:如:\d \D \w \W \s \S。
- 自定义原子表([])作为原子:如:’/[apj]sp/’ ’/[^apj]sp/’
正则表达式中常用的非打印字符
原子字符(非打印) | 含义描述 |
\cx | 匹配由x指明的控制字符。如\cM匹配一个Control-M或者回车符。x的值必须为A-Z或a-z |
\f | 匹配一个换页符。等价于\x0c或\cL |
\n | 匹配一个换行符。等价于\x0a或者\cJ |
\r | 匹配一个回车符。等价于\x0d或\cM |
\t | 匹配一个制表符。等价于\x09或\cI |
\v | 匹配一个垂直制表符。等价于\x0b或\cK |
正则表达式中常用的“通用字符类型”
原子字符(通用) | 描述含义 |
\d | [0-9] |
\D | [^0-9] |
\s | 匹配任意空白字符,等价于[\f\n\r\t\v] |
\S | 匹配出空白字符以外的字符,等价于[^\f\n\r\t\v] |
\w | 匹配人一个数字、字符、下划线,等价于[0-9a-zA-Z_] |
\W | [^0-9a-zA-Z_] |
元字符
元字符 | 含义描述 |
限定符 | 限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 |
特殊字符 | 所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo*b 中的 *,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \: runo\*ob 匹配 runo*ob。 许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面 |
^或\A | 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。 |
$或\Z | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 \[。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 \{。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 \|。 |
字符串边界限制
在某些情况下,需要对匹配范围进行限定,以获得更准确的匹配结果。^和$分别指定字符串的开始和结束。
例如:
在字符串Tom and Jerry chased each other in the house until tom’s uncel come in中
元字符“^”或“\A” 置于字符串的开始确保模式匹配出现在字符串首端;
/^Tom/
元字符“$”或“\Z” 置于字符串的结束,确保模式匹配出现字符串尾端。
/in$/
如果不加边界限制元字符,将获得更多的匹配结果。
/^Tom$/精确匹配 /Tom/模糊匹配
单词边界限制
在使用各种编辑软件的查找功能时,可以通过选择“按单词查找”获得更准确的结果。正则表达式中也提供类似的功能。
例如:
在字符串“This island is a beautiful land”中
元字符`\b`对单词的边界进行匹配;
/\bis\b/ 匹配单词“is”,不匹配“This”和“island”。
/\bis 匹配单词“is”和“island”中的“is”,不匹配“This”
元字符“\B”对除单词边界以外的部分进行匹配。
/\Bis\B/ 将明确的指示不与单词的左、右边界匹配,只匹配单词的内部。所以在这个例子中没有结果。
/\Bis 匹配单词“This”中的“is”
重复匹配
正则表达式中有一些用于重复匹配某些原子的元字符:?、*、+。他们主要的区别是重复匹配的次数不同。
元字符“?”:表示0次或1次匹配紧接在其前的原子。
例如:
/colou?r/匹配“colour”或“color”。
元字符“*”:表示0次、1次或多次匹配紧接在其前的原子。
例如:
/zo*/可以匹配z、zoo
元字符“+”:表示1次或多次匹配紧接在其前的原子。
例如:
/go+gle/匹配“gogle”、“google”或“gooogle”等中间含有多个o的字符串。
任何一个字符
元字符.匹配除换行符外任何一个字符。
相当于:^\n或^\r\n。
例如:
/pr.y/可以匹配的字符串“prey”、“pray”或“pr%y”等。
通常可以使用“.*”组合来匹配除换行符外的任何字符。在一些书籍中也称其为“全匹配符” 或 “单含匹配符”。
/^a.*z$/表示可以匹配字母“a”开头,字母“z”结束的任意不包括换行符的字符串。
/.+/ 也可以完成类似的匹配功能所不同的是其至少匹配一个字符。
/^a.+z$/ 匹配“a%z”不匹配字符串“az”。
重复匹配
元字符{ }准确地指定原子重复的次数,指定所匹配的原子出现的次数。
“{m}” 表示其前原子恰好出现m次。
“{m,n}”表示其前原子至少出现m次,至多出现n次。
“{m,}” 表示其前原子出现不少于m次。
例如:
/zo{1,3}m/ 只能匹配字符串“zom”、“zoom”、或“zooom”。
/zo{3}m/ 只能匹配字符串“zooom”。
/zo{3,}m/ 可以匹配以 “z” 开头,“m”结束,中间至少为3个“o”的字符串。
/bo{0,1}u/ 可以匹配字符串“bought a butter” 中的“bou”和“bu”,等价于bo?u。
原子表 -方括号表达式
原子表[]中存放一组原子,彼此地位平等,且仅匹配其中的一个原子。如果想匹配一个 ”a” 或 ”e” 使用 [ae]。
例如:
Pr[ae]y 匹配 ”Pray” 或者 ”Prey ”。
原子表 [^] 或者称为排除原子表,匹配除表内原子外的任意一个字符。例如:
/p[^u]/匹配“part”中的“pa”,但无法匹配“computer”中的“pu”因为“u”在匹配中被排除。
原子表[-]用于连接一组按ASCII码顺序排列的原子,简化书写。
例如:
/x[0123456789]/可以写成x[0-9],用来匹配一个由 “x” 字母与一个数字组成的字符串。
/[a-zA-Z]/匹配所有大小写字母
/^[a-z][0-9]$/匹配比如“z2”、 “t6” 、“g7”
/0[xX][0-9a-fA-F]/匹配一个简单的十六进制数字,如“0x9”。
/[^0-9a-zA-Z_]/匹配除英文字母、数字和下划线以外任何一个字符,其等价于\W。
/0?[ xX][0-9a-fA-F]+/匹配十六进制数字,可以匹配“0x9B3C”或者“X800”等。
/<[A-Za-z][A-Za-z0-9]*>/可以匹配“<P>”、“<hl>”或“<Body>”等HTML标签,并且不严格的控制大小写。
模式选择符
元字符|又称模式选择符。在正则表达式中匹配两个或更多的选择之一。
例如:
在字符串“There are many apples and pears.”中, /apple|pear/在第一次运行时匹配“apple”;
再次运行时匹配“ pear”。也可以继续增加选项,如: /apple|pear|banana|lemon/
模式单元
元字符()将其中的正则表达式变为原子(或称模式单元)使用。与数学表达式中的括号类似,“()”可以做一个单元被单独使用。
例如:
/(Dog)+/匹配的“Dog”、“DogDog”、“DogDogDog”,因为紧接着“+”前的原子是元字符“()”括起来的字符串“Dog”。
/You (very )+ old/匹配“You very old”、“You very very old”
/Hello (world|earth)/匹配“Hello world”、“Hello earth”
一个模式单元中的表达式将被优先匹配或运算。
重新使用的模式单元
系统自动将模式单元“()”中的匹配依次存储起来,在需要时可以用\1、\2、\3的形式进行引用。当正则表达式包含有相同的模式单元时,这种方法非常便于对其进行管理。注意使用时需要写成“\1”、“\2”
例如:
/^\d{2}([\W])\d{2}\\1\d{4}$/
匹配“12-31-2006”、“09/27/1996”、“86 01 4321”等字符串。
但上述正则表达式不匹配“12/34-5678”的格式。
这是因为模式“[\W]”的结果“/”已经被存储。下个位置“\1”引用时,其匹配模式也是字符“/”。
当不需要存储匹配结果时使用非存储模式单元“(?:)”
例如:
/(?:a|b|c)(D|E|F)\\1g/ 将匹配“aEEg”。
在一些正则表达式中,使用非存储模式单元是必要的。
否则,需要改变其后引用的顺序。上例还可以写成/(a|b|c)(C|E|F)\\2g/。
模式修正符
修正符 | 含义描述 |
i | 在和模式进行匹配时不区分大小写 |
m | 将字符串视为多行。默认的正则开始“^”和结束“$” 将目标字符串作为单一的“行”字符。加上n后,那么开始和结束将会指字符串的每一行 |
s | 如果设定了此修正符,模式中的圆点元字符 “.” 匹配所有的字符,包括换行符。即将字符串视为单行,换行符作为普通字符看 |
x | 模式中的空白忽略不计,除非它已经被转义 |
e | 只用在preg_replace()函数中,在替换字符串中对逆向引用做正常的替换,将其作为PHP代码求值,并用其结果来替换所搜索的字符串。 |
U | 本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上“?”才变得重复。这和perl不兼容。也可以通过在模式中设定U修正符或者在数量符之后跟一个问号(如启.*?)来用此选项。 |
D | 模式中的美元元字符仅匹配目标字符串的结尾。没有此选项时,如果最后一个字符是换行符的话,美元符号也会匹配此字符之前。如果设定了m修正符则忽略此选项。 |
贪婪匹配 匹配结果存在歧义时取长(默认)
懒惰匹配 匹配结果存在歧义时取短
U 懒惰匹配
i 忽略英文字母大小写
x 忽略空白
作者:dptms
链接:https://www.jianshu.com/p/6b7526fcd93d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。