一、前言
虽然园子里已经有很多人总结过正则了,但自己不主动整理下,别人的永远是别人的,自己动手后才不会那么快遗忘。正则表达式用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,用这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式本身作为一门语言,学习方式类似其他语言,先学词(元字符),然后学语法,最后拼接字符表达出自己想要表达的含义。
二、正则元字符
- 字符
字符 |
字符说明 |
示例 |
示例说明 |
\w |
与数字、字符、下划线以及汉字匹配 |
|
|
\d |
与十进制数字字符匹配 |
|
|
\s |
与任何空白字符匹配(空格、制表符、换行等) |
|
|
\W |
与不是数字、字符、下划线以及汉字的字符匹配 |
|
|
\D |
与非数字字符匹配 |
|
|
\S |
与非空白字符匹配 |
|
|
[character_group] |
与character_group中指定的任意单个字符匹配 |
[abc] |
匹配gray中的a |
[^character_group] |
与character_group中指定字符之外任意字符匹配 |
[^abc] |
匹配gray中的g、r、y |
[first-last] |
与指定范围中的任意单个字符匹配 |
[a-z1-9] |
匹配abCD2中的a、b、2 |
[^first-last] |
与指定范围外的任意字符匹配 |
[^a-z1-9] |
匹配abCD2中的C、D |
. |
与换行符以外的任意字符匹配 |
|
|
character_group |
与character_group指定的字符集匹配 |
ra |
匹配gray中的ra |
\ |
字符转义 |
1\.9 |
匹配1.98中的1.9 |
- 数量词
字符 |
字符说明 |
示例 |
示例说明 |
* |
匹配上一个元素零次或多次 |
\d*\.\d |
匹配88.88中的88.8,.88中的.8 |
+ |
匹配上一个元素一次或多次 |
\d+\.\d |
匹配88.88中的88.8 |
? |
匹配上一个元素零次或一次 |
\d?\.\d |
匹配88.88中的8.8,.88中的.8 |
{n} |
匹配上一个元素n次 |
\d{1}\.\d |
匹配88.88中的8.8 |
{n,} |
匹配上一个元素至少n次 |
\d{1,}\.\d |
匹配88.88中的88.8 |
{n,m} |
匹配上一个元素n到m次 |
\d{1,3}\.\d |
匹配8888.88中的888.8 |
|
|
|
|
*? |
匹配上一个元素零次或多次,但次数尽可能少 |
1\d*? |
匹配1888.88中的1 |
+? |
匹配上一个元素一次或多次,但次数尽可能少 |
1\d+? |
匹配1888.88中的18 |
?? |
匹配上一个元素零次或一次,但次数尽可能少 |
1\d?? |
匹配1888.88中的1 |
{n,} |
匹配上一个元素至少n次,但次数尽可能少 |
1\d{2,} |
匹配1888.88中的188 |
{n,m} |
匹配上一个元素n到m次,但次数尽可能少 |
1\d{2,5} |
匹配1888.88中的188 |
- 定位点
字符 |
字符说明 |
示例 |
示例说明 |
^ |
匹配字符串的开头 |
^\w{2} |
匹配123456中的12 |
$ |
匹配字符串末尾 |
\w{2}$ |
匹配123456中的56 |
\b |
匹配字符(\w)的边界(开始、结束) |
\b\w{2}\b |
匹配123 45 678中的45 |
\B |
匹配非字符边界的位置 |
bc\B |
匹配abc abcd 中第二个bc |
三、正则语法
- 分支
在编码的时候,通常有这么一种场景,字符串满足“条件1”或者“条件2”,幸运的是正则提供了类似其他语言或运算功能,当然符号也很类似,示例如下:
\b189\d{8}|\b159\d{8} 表达式匹配189开头或者159开头且长度为11的字符串。
注意:正则匹配分支顺序从左到右,若左边分支匹配成功则不再匹配剩下的条件。比较这两个表达式有什么不同 \d{5}-\d{4}|\d{5} \d{5}|\d{5}-\d{4}
- 分组
前面的示例中介绍了如何用数量词重复单个字符,例如:1\d*。那么如何重复多个字符呢?正则可以使用小括号将待重复的字符包裹起来,然后使数量词作用于被小括号包裹的整个字符集上,示例如下:
0\.(13)+ 表达式匹配0.13,13无限循环小数。
正则使用小括号指定分组后,这个分组匹配的文本,默认会缓存起来,供表达式后续使用。
分组匹配的文本每个组都自动拥有一个编号,从左向右以左小括号为标志,第一个组编号为1,依次递增。编号0表示整个正则表达式
正则指定分组时可单独为每个组指定组名,在组号分配时优先给未命名的组分配编号,然后再给指定组名的分组分配编号,因此组号分配过程需要扫描两次表达式。
js不支持分组命名
语法 |
语法说明 |
(exp) |
捕获匹配exp的字符串,并为其分配一个从1开始的编号 |
(?<group_name>exp) |
捕获匹配exp的字符串,并为其指定组名group_name,也可以写成(?‘group_name‘exp) |
(?:exp) |
匹配exp,不捕获字符串,也不分配组号 |
- 向后引用
向后引用用于重复搜索前面某个分组匹配的文本,\1表示分组1匹配的文本,\k<group_name>或者\k‘group_name‘表示组名为group_name分组匹配的文本。示例如下:
\b(\w+)\b\s+\1\s+\1\b 捕获三次重复的单词,例如:go go go
\b(?<name>\w+)\b\s+\k<name>\s+\<name>\b 捕获三次重复的单词,例如:go go go。
- 零宽断言
前面介绍正则元字符的时候提到定位点(^、$等),但是有时候我们需要自定义一些定位点,例如位置ing。像^指定一个位置,这个位置满足某种条件(即断言),我们称之为零宽断言。
断言跟前面的定位点一样分为前瞻、后瞻,js不支持后瞻断言。正向断言会消耗字符,负向断言不消耗字符。
语法 |
语法说明 |
示例 |
示例说明 |
(?=exp) |
零宽度正向前瞻,匹配后面跟的是exp的位置 |
\b\w+(?=ing) |
匹配I am writing a blog中的writ |
(?!exp) |
零宽度负向前瞻,匹配后面不是跟的exp的位置 |
\b\w{4}(?!ing) |
匹配I am writing a blog中的blog |
(?<=exp) |
零宽度正向后瞻,匹配前面跟的是exp的位置 |
(?<=wri)\w+\b |
匹配I am writing a blog中的ting |
(?<!exp) |
零宽度负向后瞻,匹配前面不是跟的exp的位置 |
(?<!wri)\w{4}\b |
匹配I am writing a blog中的blog |
四、其他
- 正则在线工具
http://regexr.com/
- 参考链接
本文主要介绍了正则的一些基础属性,若需使用此文未介绍的特性可查阅以下链接
https://msdn.microsoft.com/zh-cn/library/az24scfc.aspx
http://deerchao.net/tutorials/regex/regex.htm
正则表达式
原文:http://www.cnblogs.com/kai364/p/6198595.html