正则表达式2:https://developer.aliyun.com/article/1549163
18、字符创边界
字符串边界的元字符有两个:一个是用来定义字符串开头的^,另一个是用来定义字符串结尾的$。
^是几个有着多种用途的元字符之一。只有当它出现在一个字符集合里(被放在[和]之间)并紧跟在左方括号[的后面时,它才能发挥“求非”作用。如果是在一个字符集合的外面并位于一个模式的开头,^将匹配字符串的开头。
匹配xml,不合适的正则
匹配xml,正确的正则
字符串
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://tips.cf" xmlns:impl="http://tips.cf" xmlns:intf="http://tips.cf" xmlns:apachesoap="http://xml.apache.org/xml-soap"
正则表达式
^\s*<\?xml.*\?>
结果
<?xml version="1.0" encoding="UTF-8"?>
^匹配一个字符串的开头位置,所以^\s*将匹配一个字符串的开头位置和随后的零个或多个空白字符(这解决了<? xml>标签前允许有空格、制表符、换行符等空白字符的问题)。作为一个整体,模式^\s*<\? xml.*\? >不仅能正确地匹配一个位置正确的<? xml>标签,还能对合法的空白字符做出妥善处理。
19、子表达式
子表达式是一个更大的表达式的一部分;把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式必须用(和)括起来。
字符串
Hello,my name is Ben Forta, and I am the author of books on SQL,ColdFusion,WAP, Windows 2000,and other subjects.
正则表达式
( ){2,}
结果
( )是一个子表达式,它将被视为一个独立元素,而紧跟在它后面的{2, }将作用于这个子表达式(不仅仅是分号)。
匹配IP(简单匹配)
生产使用:
\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b
字符串
Pinging hog.forta.com[12.159.46.200] with 32 bytes of data:
正则表达式
(\d{1,3}\.){3}\d{1,3}
结果
12.159.46.200
20、回溯引用
回溯引用允许正则表达式模式引用前面的匹配结果
匹配重复单词
字符串
This isablock of of text, several words here are are repeated, and and they should not be
正则表达式
[ ]+(\w+)+[ ]+\1
结果
of of are are and and
[ ]+匹配一个或多个空格,\w+匹配一个或多个字母数字字符,[ ]+匹配随后的空格。注意,\w+是括在括号里的,它是一个子表达式。这个子表达式不是用来进行重复匹配的,这里根本不涉及重复匹配的问题。这个子表达式只是把整个模式的一部分单独划分出来以便在后面引用。这个模式的最后一部分是\1;这是一个回溯引用,而它引用的正是前面划分出来的那个子表达式:当(\w+)匹配到单词of的时候,\1也匹配单词of;当(\w+)匹配到单词and的时候,\1也匹配单词and。
匹配html
字符串
<BODY> <H1>Welcome to my Homepage</H1> Content is divided into two sections:<BR> <H2>ColdFusion</H2> Information about Macromedia ColdFusion. <H2>Wireless</H2> Information about Bluetooth,802.11,and more. <H2>Thisisnot valid HTML</H3> </BODY>
正则表达式
<[Hh][1-6]>.*?</[Hh][1-6]>
结果
<H1>Welcome to my Homepage</H1> <H2>ColdFusion</H2> <H2>Wireless</H2> <H2>Thisisnot valid HTML</H3>
原始文本里有一个标题是以<H2>开头、以<H3>结束的。这个是不合法的标题。
正则表达式
<[Hh]([1-6])>.*?</[Hh]\1>
21、回溯替换
在一个用来保存用户信息的数据库里,电话号码被保存为313-555-1234。现在,你需要把电话号码重新排版为(313)555-1234。
字符串
313-555-1234 248-555-9999 810-555-9000
正则表达式
(\d{3})(-)(\d{3})(-)(\d{4})
结果
313-555-1234 248-555-9999 810-555-9000
替换表达式
($1) $3-$5
结果
(313) 555-1234 (248) 555-9999 (810) 555-9000
这里使用了两个正则表达式模式。第1个模式看起来很复杂,我们来分析一下。(\d{3})(-)(\d{3})(-)(\d{4})用来匹配一个电话号码,它被划分为5个子表达式(5个组成部分):第1个子表达式(\d{3})匹配前3位数字,第2个子表达式(-)匹配-字符,等等。最终的结果是一个电话号码被划分成了5个部分(每个部分分别对应着一个子表达式):区号、一个连字符、电话号码的前3位数字、又一个连字符、电话号码的后4位数字。这5个部分都可以单独拿出来使用,负责重新排版电话号码的替换模式($1)$3-$5只用到了它们当中的3个,剩下的两个没有用到,但这已足以把313-555-1234转换为(313)555-1234。
22、大小写转换
23、向前查找
向前查找指定了一个必须匹配但不在结果中返回的模式。向前查找实际就是一个子表达式,而且从格式上看也确实如此。从语法上看,一个向前查找模式其实就是一个以?=开头的子表达式,需要匹配的文本跟在=的后面。
字符串
http://www.forta.com/ https://mail.forta.com ftp://ftp.forta.com/
正则表达式
.+(?=:)
结果
http https ftp
+(:)查找到并且匹配结果包含:,模式.+(? =:)查找到但匹配结果不包含:。
24、向后查找
向后查找操作符是?<=。
分不清?=、? <=与其他?的话,有个简单的办法可以帮你分辨它们:有小于号的是向后查找操作符——你可以把这个小于号想像成一个箭头,它指向文本阅读方向的后方。
字符串
ABC01: $23.45 HGG42: $5.31 CFMX1: $899.00 XTC99: $69.96 Total items found:4
正则表达式
(?<=\$)[\d.]+
结果
23.45 5.31 899.00 69.96
25、 对前后查找取非
负向前查找(negative lookahead)将向前查找不与给定模式相匹配的文本,负向后查找(negative lookbehind)将向后查找不与给定模式相匹配的文本。
匹配价格
字符串
I paid $30 for 100, apples,50 oranges,and 60 pears. I saved $5 on this order.
正则表达式
(?<=\$)[\d]+
结果
30 5
匹配数量