正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用正则表达式进行字符串操作。
测试地址:
https://c.runoob.com/front-end/854/
常用表达式
https://blog.csdn.net/qq_29752857/article/details/123344971
.字符(英文句号)可以匹配任何一个单个的字符。
.字符可以匹配任何单个的字符、字母、数字甚至是.字符本身。
- sales1.xls
- orders3.xls
- sales2.xls
- sales3.xls
- apac1.xls
- europe2.xIs
- na1.xls
- na2.xls
- sa1.xls
正则表达式
sales.
匹配结果
- sales1
- sales2
- sales3
.字符在正则表达式里有着特殊的含义。如果模式里需要一个.,就要想办法来告诉正则表达式你需要的是.字符本身而不是它在正则表达式里的特殊含义。为此,你必须在.的前面加上一个\(反斜杠)字符来对它进行转义。
原始字符串:
- sales1.xls
- orders3.xls
- sales2.xls
- sales3.xls
- apac1.xls
- europe2.xIs
正则表达式:
sales.\.xls
匹配结果
- sales1.xls
- sales2.xls
- sales3.xls
在正则表达式里,我们可以使用元字符[和]来定义一个字符集合。在使用[和]定义的字符集合里,这两个元字符之间的所有字符都是该集合的组成部分,字符集合的匹配结果是能够与该集合里的任意一个成员相匹配的文本。
原始字符串:
- sales1.xls
- orders3.xls
- sales2.xls
- sales3.xls
- apac1.xls
- europe2.xls
- na1.xls
- na2.xls
- sa1.xls
- ca1.xls
正则表达式:
[ns]a.\.xls
匹配结果:
- na1.xls
- na2.xls
- sa1.xls
在使用正则表达式的时候,会频繁地用到一些字符区间(0~9、A~Z,等等)。为了简化字符区间的定义,正则表达式提供了一个特殊的元字符——字符区间可以用-(连字符)来定义。
(连字符)是一个特殊的元字符,作为元字符它只能用在[和]之间。在字符集合以外的地方,-只是一个普通字符,只能与-本身相匹配。因此,在正则表达式里,-字符不需要被转义。
在定义一个字符区间的时候,一定要避免让这个区间的尾字符小于它的首字符(例如[3-1])。这种区间是没有意义的,而且往往会让整个模式失效。
原始字符创:
- sales1.xls
- orders3.xls
- sales2.xls
- sales3.xls
- apac1.xls
- europe2.xls
- na1.xls
- na2.xls
- sa1.xls
- ca1.xls
正则表达式:
- [ns]a[0123456789]\.xls
- [ns]a[0-9]\.xls
匹配结果:
- na1.xls
- na2.xls
- sa1.xls
用元字符^来表明你想对一个字符集合进行取非匹配——这与逻辑非运算很相似。
原字符串:
- sales1.xls
- orders3.xls
- sales2.xls
- sales3.xls
- apac1.xls
- europe2.xls
- sam.xml
- na1.xls
- na2.xls
- sa1.xls
- ca1.xls
正则表达式:
[ns]a[^0-9]\.xml
结果:
sam.xml
- #字符串
- abc
- abd
- ab2
- ab1
- ,。,。,。
-
- #正则表达式
- ab[\d]
-
- #结果
- ab2
- ab1
- #字符串
- 11213
- A1C2E3
- 48075
- 48237
- M1B4F2
- 90046
- H1H2H2
-
- #正则表达式
- \w\d\w\d\w\d
-
- #结果
- A1C2E3
- M1B4F2
- H1H2H2
在正则表达式里,十六进制(逢16进1)数值要用前缀\x来给出。比如说,\x0A对应于ASCII字符10(换行符),其效果等价于\n。
在正则表达式里,八进制(逢8进1)数值要用前缀\0来给出,数值本身可以是两位或三位数字。比如说,\011对应于ASCII字符9(制表符),其效果等价于\t。
这里使用的模式以[[开头、以]]结束(两对方括号)。这是使用POSIX字符类所必须的。POSIX字符类必须括在[:和:]之间,我们使用的POSIX字符类是[:xdigit:](不是:xdigit:)。外层的[和]字符用来定义一个字符集合,内层的[和]字符是POSIX字符类本身的组成部分。
+匹配一个或多个字符(至少一个;不匹配零个字符的情况)。
[0-9]+将匹配一个或多个连续的数字。
字符串
Send personal email to ben@forta.com orben.forta@forta.com. For questions about abook use support@forta.com. If your messageis urgent try ben@urgent.forta.com. Feelfree to send unsolicited email tospam@forta.com (wouldn't it be nice ifit were that simple, huh?).
正则表达式
[\w.]+@[\w.]+\.\w+
结果
- ben@forta.com
- orben.forta@forta.com
- support@forta.com
- ben@urgent.forta.com
- tospam@forta.com
这种匹配需要用*元字符来完成。*的用法与+完全一样——只要把它放在一个字符(或一个字符集合)的后面,就可以匹配该字符(或字符集合)连续出现零次或多次的情况。
字符串
Hello .ben@forta.com is my email address
正则表达式
\w[\w.]*@[\w.]+\.\w+
结果
ben@forta.com
?只能匹配一个字符(或字符集合)的零次或一次出现,最多不超过一次——请仔细体会?与+和*的相似和区别之处。如果需要在一段文本里匹配某个特定的字符(或字符集合)而该字符可能出现、也可能不出现,?无疑是最佳的选择。
字符串
The URL is http://www.forta.com/,to connectsecurely use https://www.forta.com/ instead.
正则表达式
https?://[\w./]+
这个模式的开头部分是https?。?在这里的含义是:我前面的字符(s)要么不出现,要么最多出现一次。换句话说,https?://既可以匹配http://,也可以匹配https://,但也就仅此而已。
结果
- http://www.forta.com/
- https://www.forta.com/
这种写法可读性更强。
{}语法还可以用来为重复匹配次数设定一个区间——也就是为重复匹配次数设定一个最小值和一个最大值。这种区间必须以{2, 4}这样的形式给出——{2, 4}的含义是最少重复2次、最多重复4次。在下面的例子里,我们将使用一个这样的正则表达式来检查日期的格式:
字符串
- 4/8/03
- 10-6-2004
- 2/2/2
- 01-01-01
正则表达式
\d{1,2}[-\/]\d{1,2}[-\/]\d{2,4}
结果
- 4/8/03
- 10-6-2004
- 01-01-01
{3, }表示至少重复3次,与之等价的说法是“必须重复3次或更多次”
字符串
- 1001: $496.80
- 1002: $1290.69
- 1003: $26.43
- 1004: $613.42
- 1005: $7.61
- 1006: $414.90
- 1007: $25.00
正则表达式
\d+: \$\d{3,}\.\d{2}
结果
- 1001: $496.80
- 1002: $1290.69
- 1004: $613.42
- 1006: $414.90
*和+都是所谓的“贪婪型”元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止的。
懒惰型元字符的写法很简单,只要给贪婪型元字符加上一个?后缀即可。
字符串
This offer is not available to customersliving in AK and HI
正则表达式
<[Bb]>.*?[Bb]>
结果
- AK
- HI
过度匹配
非过度匹配
限定符\b指定的单词边界。\b用来匹配一个单词的开始或结尾。
字符串
The cat scattered his food all over the room.
正则表达式
\bcat\b
结果
cat
字符串边界的元字符有两个:一个是用来定义字符串开头的^,另一个是用来定义字符串结尾的$。
^是几个有着多种用途的元字符之一。只有当它出现在一个字符集合里(被放在[和]之间)并紧跟在左方括号[的后面时,它才能发挥“求非”作用。如果是在一个字符集合的外面并位于一个模式的开头,^将匹配字符串的开头。
匹配xml,不合适的正则
匹配xml,正确的正则
字符串
- "1.0" encoding="UTF-8"?>
"http://tips.cf" - xmlns:impl="http://tips.cf" xmlns:intf="http://tips.cf"
- xmlns:apachesoap="http://xml.apache.org/xml-soap"
正则表达式
^\s*<\?xml.*\?>
结果
"1.0" encoding="UTF-8"?>
^匹配一个字符串的开头位置,所以^\s*将匹配一个字符串的开头位置和随后的零个或多个空白字符(这解决了 xml>标签前允许有空格、制表符、换行符等空白字符的问题)。作为一个整体,模式^\s*<\? xml.*\? >不仅能正确地匹配一个位置正确的 xml>标签,还能对合法的空白字符做出妥善处理。
子表达式是一个更大的表达式的一部分;把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式必须用(和)括起来。
字符串
- 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
回溯引用允许正则表达式模式引用前面的匹配结果
匹配重复单词
字符串
- 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
字符串
Welcome to my Homepage
- Content is divided into two sections:
ColdFusion
- Information about Macromedia ColdFusion.
Wireless
- Information about Bluetooth,802.11,and more.
Thisisnot valid HTML
正则表达式
<[Hh][1-6]>.*?[Hh][1-6]>
结果
Welcome to my Homepage
ColdFusion
Wireless
Thisisnot valid HTML
原始文本里有一个标题是以开头、以
结束的。这个是不合法的标题。
正则表达式
<[Hh]([1-6])>.*?[Hh]\1>
在一个用来保存用户信息的数据库里,电话号码被保存为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。
向前查找指定了一个必须匹配但不在结果中返回的模式。向前查找实际就是一个子表达式,而且从格式上看也确实如此。从语法上看,一个向前查找模式其实就是一个以?=开头的子表达式,需要匹配的文本跟在=的后面。
字符串
- http://www.forta.com/
- https://mail.forta.com
- ftp://ftp.forta.com/
正则表达式
.+(?=:)
结果
- http
- https
- ftp
+(:)查找到并且匹配结果包含:,模式.+(? =:)查找到但匹配结果不包含:。
向后查找操作符是?<=。
分不清?=、? <=与其他?的话,有个简单的办法可以帮你分辨它们:有小于号的是向后查找操作符——你可以把这个小于号想像成一个箭头,它指向文本阅读方向的后方。
字符串
- 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
负向前查找(negative lookahead)将向前查找不与给定模式相匹配的文本,负向后查找(negative lookbehind)将向后查找不与给定模式相匹配的文本。
匹配价格
字符串
- I paid $30 for 100,
- apples,50 oranges,and 60 pears.
- I saved $5 on this order.
正则表达式
(?<=\$)[\d]+
结果
- 30
- 5
匹配数量