子表达式
子表达式是一个更大的表达式的一部分。子表达式必须用()
来定义。
子表达式用于对表达式进行分组和归类。类似于优先级的意思,()
里的优先级高
例:匹配IP
IP地址的格式是以英文句号分隔的四组数字,每组数字由1个、2个、或3个数字字符组成。如12.111.46.231
普通正则表达式
\d{1.3}\.\d{1.3}\.\d{1.3}\.\d{1.3}
\d{1.3}\
匹配任意1-3个数字。.匹配.
用子表达式写法如下
(\d{1.3}\.){3}\d{1.3}
把\d{1.3}\.
看成一个子表达式,出现了三次(\d{1.3}\.){3}
这个表达式匹配到了想要的内容,但是也匹配到了不符合条件的内容。比如300.1.23.333就是不是一个有效的IP地址(最大255)
优化如下:
列举出所有的条件
- 任何一个1位或2位数字
- 任何一个以1开头的3位数字
- 任何一个以2开头、第2位数字在0~4之间的3位数字
- 任何一个以25开头、第3位数字在0~5之间的3位数字
正则表达式如下
(((\d{1.2})|1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1.2})|1\d{2})|(2[0-4]\d)|(25[0-5]))
分析表达式的时候应该按照先内后外的原则进行。
注:
|
是或者的意思。表示|
两边的都可以
回溯引用
回溯引用指的是模式的后半部分引用在前半部分中定义的子表达式,即回溯引用的作用是引用正则表达式前面的匹配结果
注:回溯引用只能引用模式里的子表达式
(子表达式1)(子表达式2)(子表达式3)\1\2\3
\1
代表模式里的第一个子表达式、\2
代表模式里的第二个子表达式、\3
代表模式里的第三个子表达式。以此类推
注:有些语言(如JavaScript)回溯引用语法用$
不用\
。如:$1$2$3
回溯引用的缺点:如果子表达式的相对位置发生了变化,整个模式也许就不能再完成原来的工作,删除或添加子表达式的后果可能更严重。
例1 前后一致匹配
匹配所有的标题标签及内容
<body>
<h1>hello world</h1>
<span>haha</span>
<h2>hello go<h3>
<div>heihei</div>
<h3>hello docker</h3>
</body>
正则表达式
<hH>([1-6])>.*?</hH>\1>
匹配到
<h1>hello world</h1>
<h3>hello docker</h3>
<h2>hello go<h3>
前后标签不一致匹配不到(实际是错误的标签)
解析
([1-6])
是一个子表达式,后面的\1
将再一次匹配它本身。如1就匹配1,2就匹配2。
.*?
懒惰匹配,将匹配任意一个字符零次或多次
例2 替换
将电子邮箱地址替换成可点击的链接
hello,ghongxiang@outlook.com is my email address.
正则表达式
(\w+[\w\.]*@[\w\.]+\.\w+)
替换
<a href="mailto:\1">\1</a>
mailto是电子邮件协议,通过该协议可以创建一个指向电子邮件地址的超级链接,点击该超链接就会打开OE等邮件客户端程序,输入相应的内容后就可以向此邮箱地址发送邮件
结果
hello,<a href="mailto:ghongxiang@outlook.com">ghongxiang@outlook.com</a> is my email address.
网友评论