英文名:Regular Expression,常简写为regex,计算机科学的一个概念。它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,它通常被用来检索、替换符合某个模式的文本。
概念
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
给定一个正则表达式和一个字符串,可以达到如下目的:
- 给定的字符串是否符合正则表达式的过滤逻辑,如在注册页面验证邮箱地址是否正确
- 可能通过正则表达式,从字符串中获取想要的特定部分
由于正则表达式的应用对象多为文本,因此在各种文本编辑器里广泛使用。
一些元字符及其描述:
^ 匹配输入字符串的开始位置$ 匹配输入字符串的结束位置,这两个在VIM里常用到. 匹配除”\n”外的任何单个字符,包括空格。如s.d可以匹配sad或s d* 匹配前面的子表达式0-n次。如tu匹配t/tu/tuu/tuuu/…+ 1-n次。如tu+匹配tu/tuu/tuuu/…? 0-1次。如tu(rui)?匹配tu/turui{n} n为非负整数,匹配确定的n次。如fo{2}d匹配food{n,} 至少n次。{0,}等效于`,{1,}等效于+{n,m}n-m次x|y匹配x或y。如I love (you|her)匹配I love you or I love her[xyz]匹配xyz里任意一个字符,也就是在括号内出现的一个字符,要么x,要么y,要么z。[a-z]匹配a-z这26个字符里的任意一个字符。[^xyz]不出现xyz里的任一字符\d匹配一个数字,等价于[0-9]\D不匹配数字,等价于[^0-9]\n换行\r回车[0-9]{4,6}` 组合技,匹配任意的4位数,5位数,6位数
Ubuntu中正则的应用
假设文件test中有如下内容:1
2
3
4
5
6
7
8
9
10
11
12"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $3183 dollars.^M
GNU is free air not free beer.^M
Her hair is very beauty.^M
Oh! The soup taste good.^M
foooood & food & foood.
以之前介绍过的grep命令grep 参数 正则表达式 文件为例:grep -n 'f..[dt]' test,就匹配了第2行的food和第4行的feet。但是不匹配第4行的Football,因为正则区分大小写。
grep -n '^G' text匹配以G开关的第9行。代表以G开关的行。
grep -n 'soup' text加上个参数-v则反向输出显示,该例是显示带soup的第11行,而参数-nv则显示除第8行的其他行,参数-i表示忽略大小写。
grep -n '^[Ft]' text显示以F或t开关的第4和第5行。
grep -n '^[a-z]' text以小写开关的行全列出,第2和第5行。上面这条等价于:grep -n '^[[:lower:]]' text
这里要强调的是^在[]内是指反向选择,在[]外则是选择开头。
grep -n 'ooo*' text文本中至少两个o,因为第三个o表示0-无穷个,第1/2/4/11/12行。.*代表零至任意个任意字符,要找gxxxd可以g.*d。
grep -n 'fo\{2,5\}g' textf开头,两到五个o,以g结尾
^word指以word开头的行,word$以word结尾的行
grep -n \' text搜索含有单引号的行。如果要显示文本的第5-9行。可以这样:cat -An text | head -n 10 | tail -n 6。
其中head命令表示text的前10行,然后在这前10里取后6行。再来一正则例,dmesg是用来显示开机信息的一条linux命令,其内容在/var/log/dmesg里。dmesg | grep -n 'eth'“|”代表将前面的dmesg的结果传递给后面的grep,前面已出现过|,这条组合命令其实等价于:grep -n 'eth' /var/log/dmesg,”-n”显示”eth”出现在dmesg的第多少行。在我的电脑里这条命令的结果是:1
2
3
4
5
6
7
8705:[ 5.875958] tg3 0000:01:00.0 eth0: Tigon3 [partno(BCM95906) rev c002] (PCI Express) MAC address 00:1f:16:1c:87:57
706:[ 5.875964] tg3 0000:01:00.0 eth0: attached PHY is 5906 (10/100Base-TX ethernet) (WireSpeed[0], EEE[0])
707:[ 5.875967] tg3 0000:01:00.0 eth0: RXcsums[1] LinkChgREG[0] MIirq[0] ASF[0] TSOcap[0]
708:[ 5.875970] tg3 0000:01:00.0 eth0: dma_rwctrl[76180000] dma_mask[64-bit]
726:[ 11.505641] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
775:[ 18.745684] eth1: Broadcom BCM4315 802.11 Hybrid Wireless Controller 6.20.155.1 (r326264)
804:[ 31.537161] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
805:[ 31.537638] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
dmesg | grep -n -A3 -B2 eth将含eth的前两行和后三行一起显示。因为ls命令不支持正则表达式,所以:ls -l t*来表示显示以t开头的文件或目录。利用sed来显示文本中的第n-m行,如下:nl /etc/passwd | sed -n '3,5p'它将显示passwd文本中的第3到第5行。不显示11-22行:nl /etc/passwd | sed '11,22d'。不显示第3至最后一行nl /etc/passwd | sed '3,$d'。用No 2-5 number改变第2-5行的内容:nl /etc/passwd | sed '2,5c nl /etc/passwd | sed '2,5c No 2-5 number''。使用-i可以直接修改内容,如将句尾的.换成!sed -i 's/\.$/\!/g' text。在最后一行添加内容: sed -i '$a #this is a text' text。将文本中空行和注释行去除:grep -v '^$' text | grep -v '^#'。上面的命令合并为一条命令:egrep -v '^$|^#' text。
JavaScript正则表达式
1 | var str = 'a{bc}de'; |
RegExp类型(正则表达式):/pattern/flags;。如var pattern = /.at/gi; //匹配所有以at结尾的组合,不区分大小写,元字符([{\^$|?*+.}])需要转义。
正则表达式在线测试网站:站长之家 & Regulex*%3F%24)
1 | var text = '0755-1234-5678'; |
对比:1
2
3
4pattern.test(str); //boolean
pattern.exec(str); //返回数组
str.match(pattern); //返回数组
str.replace(pattern, string or func);
1 | var s = 'hello world'.replace(/(\w+)\s(\w+)/, function($1, $2, $3) { |