正则表达式这个东西确实有点复杂,要是每次都从头写挺麻烦的,所以就把平时会用到的都记录到这儿。
在线正则表达式测试以及性能分析工具:https://regex101.com/
有一个搜索正则非常棒的方法,直接在google
输入类似regex email
等内容,出来的第一条会是谷歌提供的格式化的搜索结果。
正则表达式引擎的实现方式:
DFA自动机(Deterministic Final Automata确定型有穷自动机): 时间复杂度是线性的,更加稳定,但是功能有限
NFA自动机(Non deterministic Finite Automaton不确定型有穷自动机): 时间复杂度不稳定,有时很好有时很差,大多数编程语言使用的是NFA,由于不稳定,所以对于复杂的语句我们有时候需要优化一下。
正则匹配是一个CPU密集型的任务,如果出现CPU被占满性能依然不够的情况,可以用上述性能分析网站看是否有灾难性回溯的出现,如果没有,可以考虑换一种更适合业务场景的算法,例如敏感词过滤推荐使用DFA算法,最后,实在不行,只有提高CPU了。
字符 |
说明 |
^ |
匹配字符串开始的位置 |
$ |
匹配字符串结束的位置 |
* |
零次或多次匹配前面的字符或子表达式,例如,zo*匹配z和zoo |
+ |
一次或多次匹配前面的字符或子表达式,例如zo+匹配zo和zoo但不匹配z |
? |
零次或一次匹配前面的字符或子表达式,例如zo?匹配z和zo但不匹配zoo |
\w |
匹配所有非特殊字符 |
\W |
匹配所有特殊字符 |
[] |
包括里面的字符 |
[^] |
排除里面的字符 |
[^\W] |
排除所有的非特殊字符 |
[\w]+或\w+ |
匹配数字、字母以及下划线(即非特殊字符) |
[\w-+]+ |
匹配数字、字母、下划线以及-、+ |
{n} |
刚好匹配n次,例如 o{2}与”Bob”中的”o”不匹配,但与”food”中的两个”o”匹配 |
{n,} |
至少匹配n次 |
{n,m} |
匹配至少n次,至多m次。不填m表示不限最大数量 |
. |
匹配除”\n”之外的任何单个字符,要匹配任意字符应该使用([\s\S]*),这种方法包括了换行符的 |
.* |
匹配任意字符,最长匹配(贪婪型的,比如(.)/就表示遇到最后一个/就结束) |
.*? |
匹配任意字符,最段匹配(贪婪型的,比如(.)/就表示遇到第一个/就结束),包括换行符就是([\s\S]*?) |
?= |
零宽断言,先从要匹配的字符串中的最右端找到第一个匹配项,然后再匹配前面的表达式,例如[a-z](?=ing)可以匹配cooking singing中的cook与sing,.(?=ing)可以匹配cooking singing中的cooking sing而不是cook,同样,这样的表达式可以匹配多次,适合找前缀和后缀的情况 |
\d |
匹配一个数字 |
\n |
匹配一个换行符 |
\f |
匹配一个换页 |
\r |
匹配一个回车符 |
\t |
匹配一个制表符 |
\v |
匹配一个垂直制表符 |
\s+ |
匹配一个或多个空白 |
| |
或者,最好把两个条件都用小括号括起来,例如(a|b) |
() |
在匹配的时候没什么作用,主要用于程序提取匹配到的字符串 |
(?i) |
后面的内容忽略大小写 |
|
|
常用正则表达式
正则表达式收藏网站
https://github.com/geongeorge/i-hate-regex
社交平台常用正则表达式
匹配URL/IP地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 匹配URL,来自stackoverflow.com https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*) # 上述表达式的不含http版本 [-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*) # 但是上面的还是有一点缺陷,比如会认为,..abc这种是正确的,所以在stackoverflow找到另外一个,现在最常用的是下面这个 ^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$
# 匹配IPv4地址 ^(?=.*[^\.]$)((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.?){4}$
# 获取url中的domain和request (https*:\/\/)*(?<domain>.*?)\/(?<request>.*)
# 获取URL中各个字段 ^(?:(\w+):\/\/)?(?:(\w+):?(\w+)?@)?([^:\/\?#]+)(?::(\d+))?(\/[^\?#]+)?(?:\?([^#]+))?(?:#(\w+))? # 例如在js中 home = 'http://www.haofly.net/user/cp-cpi' home.match(/该正则表达式/) # 结果是 ["http://www.haofly.net/user/cp-api", "http", undefined, undefined, "www.haofly.net", undefined, "/user/cp-api", undefined, undefined]
|
匹配内网地址IPv4
1 2 3 4
| (^127\.)| (^10\.)| (^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)| (^192\.168\.)
|
匹配域名
1 2 3
| ^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\.[a-zA-Z]{2,11}?$
^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,6}$ # 仅仅匹配域名
|
匹配数字
匹配Emali地址:
\\w+([-+.]\\w+)_@\\w+([-.]\\w+)_.\\w+([-.]\\w+)__
匹配帐号(字母开头,允许6-20字节,允许字母数字下划线)
1 2 3
| ^[a-zA-Z][a-zA-Z0-9_]\{5,19\}$ # 如果可以有中文,就写成这样 ^[a-zA-Z\\u4e00-\\u9fa5][0-9a-zA-Z\\u4e00-\\u9fa5]\{1,90\}$
|
匹配座机和手机号码,如12341234,12345678901
匹配密码
1
| ^[\\@A-Za-z0-9!#\\$\\\%\\^\\&_.\\~]\{6,22\}$
|
匹配特殊符号(这些是建立文件夹时需要去掉的特殊符号)
匹配6位字符表示的颜色值,如#ffffff
非零开头正整数
字符串不包含某个字符串
1
| ^((?!test).)*$ # 这里*表示匹配一次还是多次,.表示每个字符都去试一下,?!表示否定式向前查找。相当于反向每个字符都判断一下,它前面是不是那个字符串
|
包含且不包含
1
| ^((?!重庆).)*上海((?!重庆).)*$ # 包含上海且不包含重庆
|
移除HTML中的注释
扩展阅读