【正则表达式】总结




前言

正则表达式在匹配字符串文本时很是出色,而且在不少语言中都支持正则表达式。css

我概括整理了下学习正则表达式时的知识点,因此就写了这篇博客。html


1、正则表达式

1.概念

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式一般被用来检索、替换那些符合某个模式(规则)的文本。java

正则表达式是对字符串操做的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。git

正则表达式(Regular expression),咱们经常使用regex缩写来表示正则表达式。github

简单来讲,正则表达式就是一串有规则的字符串。这个有规则的字符串用来匹配另外一个字符串。web

2.做用

给定一个正则表达式和另外一个字符串,咱们能够达到以下的目的:正则表达式

  1. 给定的字符串是否符合正则表达式的过滤逻辑(称做“匹配”);
  2. 能够经过正则表达式,从字符串中获取咱们想要的特定部分。

用一个有规则的字符串(正则表达式)去匹配另外一个字符串,能够判断是否匹配,也能够从另外一个字符串中获取咱们想要的特定部分(好比:你要判断用户输入的用户名是否规范,可使用正则表达式来进行匹配)。express

3.特色

正则表达式的特色是:svg

  1. 灵活性、逻辑性和功能性很是强;
  2. 能够迅速地用极简单的方式达到字符串的复杂控制。
  3. 对于刚接触的人来讲,比较晦涩难懂。

正则表达式很是灵活,而且能够用很简单地用一串正则表达式去匹配一个字符串(好比:用代码控制会写不少代码,可是正则表示可能就一行)。学习

虽然刚开始接触会感受比较难,万事开头难嘛,可是多学一些以后会感受很是简单了!

4.初识正则表达式

4.1 准备
  • 软件
    我用来学习正则表达式软件是 RegexBuddy推荐使用 百度下载一下会简单使用便可)。
    简单使用:

  • 网站
    若是你想用网站,我推荐的是菜鸟教程 正则表达式在线测试 网站
    连接:https://c.runoob.com/front-end/854

4.2 基础练习

正则表达式能够分开学的,能够先使用软件或网站练习。

等熟悉了经常使用的正则表达式后,再到经常使用的语言中使用正则表达式。

  • 问题:给定一个字符串"hello regex 123,456",找出字符串中的全部数(尽量大)。

  • 解决:使用正则的元字符(特殊意义的字符)和限定符(重复的次数)便可。(元字符和限定符我下面会讲到)

  • 正则表达式:\d+[0-9]+


2、正则表达式基础

1.元字符(特殊字符)

正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。元字符使正则表达式具备处理能力。所谓元字符就是指那些在正则表达式中具备特殊意义的专用字符,能够用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

正则表达式主要依赖于元字符。 元字符不表明他们自己的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思。

元字符就是一些特殊意义的专用字符。元字符解释:一组代替一个或多个字符的字符。

1.1 简写字符集(可打印字符)

可打印字符就是在显示器上输出可以看得见的。

如:在ASCII表中,打印字符是指除ASCII码0~31及127(共33个)是控制字符或通讯专用字符,剩余的都属于可打印字符。

字符 描述
. 匹配除换行符 \n 以外的任何单字符。
\d 匹配数字: [0-9]
\D 匹配非数字: [^\d]
\w 匹配全部字母数字,等同于 [a-zA-Z0-9_]
\W 匹配全部非字母数字,即符号,等同于: [^\w]
[ ] 字符集合。匹配所包含的任意一个字符(经常使用0-9表示0到9,a-z表示小写字母a到z,大写字母同理)。例如 [abcde] 能够匹配到 “hello” 中的 ‘e’。
1.2 简写字符集(非打印字符)

什么是非打印字符呢?非打印字符指在计算机中有一些字符是确确实实存在,可是它们不可以显示或者打印出来。

如:在ASCII表中,非打印字符是指ASCII码0~31及127(共33个)是控制字符或通讯专用字符,属于非可打印字符。

字符 描述
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。不然,将 c 视为一个原义的 ‘c’ 字符。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
1.3 限定符

限定符用来指定正则表达式的一个给定组件必需要出现多少次才能知足匹配。有 ? 或 * 或 + 或 {n} 或 {n,} 或 {n,m} 共6种。

限定符就是用来指定某一个正则表达式须要重复多少次才匹配。

字符 描述
? 匹配前面的子表达式零次或一次。    如:cs? 表示匹配前面s能够出现零次或一次(s能够重复0或1次),能够匹配到 c、cs可是不能匹配到css
* 匹配前面的子表达式零次或屡次。    如:cs* 表示匹配前面s能够出现零次或屡次(s能够重复0次以上),能够匹配到 c、cs、css
+ 匹配前面的子表达式一次或屡次。    如:cs+ 表示匹配前面s能够出现一次或屡次(s能够重复1次以上),能够匹配到 cs、css,可是不能匹配到c
{n} n 是一个非负整数。匹配肯定的 n 次。  如:cs{2} 表示匹配前面s出现2次(s能够重复2次以上),能够匹配到 css,可是不能匹配到c、cs、csss
{n,} n 是一个非负整数。至少匹配n 次。    如:cs{2,} 表示匹配前面s至少2次及以上(s能够重复2以上),能够匹配到 css、csss、可是不能匹配到cs
{n,m} n 和 m 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。  如:cs{2,4} 表示匹配前面s至少2次最多4次(s能够重复2-4次),能够匹配到 css、csss可是不能匹配到cs
1.4 定位符

定位符使您可以将正则表达式固定到行首或行尾。它们还使您可以建立这样的正则表达式,这些正则表达式出如今一个单词内、在一个单词的开头或者一个单词的结尾。
定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

字符 描述
^ 匹配输入字符串的开始位置。^的另外一种用法:在方括号表达式中使用(如[^ ]),当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。
$ 匹配输入字符串的结尾位置。
\b 匹配一个单词边界,即字与空格间的位置。
\B 非单词边界匹配。
1.5 特殊字符

特殊字符就是指有特殊意义的字符。若是须要用到特殊字符的本来字符,须要使用转义字符 \ 进行转义(如:你想匹配 ^ 字符,则须要这样写 \^)。

字符 描述
\        将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\”,而 ‘\(’ 则匹配 “(”。
. 匹配除换行符 \n 以外的任何单字符。
? , * , +, { } 请查看上面1.3 限定符。
^ 和 $ 请查看上面1.4 定位符。
( ) 捕获组,用来把正则表达式中子表达式匹配的内容,保存到内存中,用数字标号或显示命名的组里,方便后面引用。
[ 表示字符集合的开始。常常与 ] 搭配使用,[] 表示字符集合,匹配所包含的任意一个字符。例如 [abcde] 能够匹配到 “hello” 中的 ‘e’。
| 或运算符。例如,正则 c|s 将匹配 c 或者 s

3、正则表达式进阶

1.零宽断言

用于查找在某些内容(但并不包括这些内容)以前或以后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该知足必定的条件(即断言),所以它们也被称为零宽断言。

这名词可能有点难理解,我用个人理解来解释一下:

  • 零宽:就是0宽度,没有宽度(就是正则匹配时不包含这些内容)。

  • 断言:判定某个位置知足必定条件的言论(就是判定某个位置,这个位置应该是知足必定条件的)。

  • 零宽断言简单理解:就是像定位符 \b,^,$ 同样用来指定某个位置,判定某个位置必定有知足某个条件的表达式。

字符 描述
(?=pattern)                               正向确定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不须要获取供之后使用。例如,“Windows(?=95|98|NT|2000)“能匹配"Windows2000"中的"Windows”,但不能匹配"Windows3.1"中的"Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配以后当即开始下一次匹配的搜索,而不是从包含预查的字符以后开始。
(?<=pattern) 反向(look behind)确定预查,与正向确定预查相似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。
(?!pattern) 正向否认预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不须要获取供之后使用。例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配以后当即开始下一次匹配的搜索,而不是从包含预查的字符以后开始。
(?<!pattern) 反向否认预查,与正向否认预查相似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
1.1 正向确定预查

正向确定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不须要获取供之后使用。例如,“Windows(?=95|98|NT|2000)“能匹配"Windows2000"中的"Windows”,但不能匹配"Windows3.1"中的"Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配以后当即开始下一次匹配的搜索,而不是从包含预查的字符以后开始。

  • 语法:(?=pattern)
  • 正则: Windows(?=95|98|NT|2000)
  • 正则解释:匹配Windows,后面为95或98或NT或2000的字符串(匹配结果仅包含Windows)。
1.2 反向确定预查

反向(look behind)确定预查,与正向确定预查相似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。

  • 语法:(?<=pattern)
  • 正则: (?<=95|98|NT|2000)Windows
  • 正则解释:匹配Windows,前面为95或98或NT或2000的字符串(匹配结果仅包含Windows)。
1.3 正向否认预查

正向否认预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不须要获取供之后使用。例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配以后当即开始下一次匹配的搜索,而不是从包含预查的字符以后开始。

  • 语法:(?!pattern)
  • 正则: Windows(?!95|98|NT|2000)
  • 正则解释:匹配Windows,后面为95或98或NT或2000的字符串(匹配结果仅包含Windows)。
1.4 反向否认预查

反向否认预查,与正向否认预查相似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。

  • 语法:(?<!pattern)
  • 正则: (?<!95|98|NT|2000)Windows
  • 正则解释:匹配Windows,前面 为95或98或NT或2000的字符串(匹配结果仅包含Windows)。

4、正则表达式补充

1.捕获

字符 描述
( ) 捕获组,用来把正则表达式中子表达式匹配的内容,保存到内存中,用数字标号或显示命名的组里,方便后面引用。
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供之后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是颇有用。例如, 'industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
1.1 捕获组

捕获组,用来把正则表达式中子表达式匹配的内容,保存到内存中,用数字标号或显示命名的组里,方便后面引用。

捕获组 () 咱们在 2、正则表达式基础的 中的 1.5 特殊字符 看到过。

正则表达式会左侧开始,每出现一个左括号"("记作一个分组,分组编号从 1 开始。0 表明整个表达式。

  • 语法:(pattern)
  • 正则: ([1-9])(\d)
  • 正则解释:匹配一个两位数。([1-9])为捕获组1,表示1-9开头的数。(\d)为捕获组2,表示任意一个数(匹配结果包含12)。
1.2 反向引用

匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。

上面讲的捕获组,会给每一对括号记做一个分组,分组编号从 1 开始。0 表明整个表达式。如今咱们学捕获组的引用(反向引用)。

  • 语法:\num
  • 正则: ([1-9])(\d)\2
  • 正则解释:匹配一个三位数。([1-9])为捕获组1,表示1-9开头的数。(\d)为捕获组2,表示任意一个数。\2表示反向引用捕获组2( 即(\d) )(匹配结果包含122)。
1.3 非捕获组

匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供之后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是颇有用。例如, 'industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。

  • 语法:(?:pattern)
  • 正则: industr(?:y|ies)
  • 正则解释:匹配industr,结尾为y或ies的字符串(匹配结果包含y和ies)。

2.贪婪匹配与非贪婪匹配 + 否认字符集

‘?’ 和 ‘^’ 这两个元字符咱们在 2、正则表达式基础的 中的 1.3 限定符1.4 定位符 看到过。

字符 描述
?     当该字符紧跟在任何一个其余限制符 (*, +, ?, {n}, {n,}, {n,m} ) 后面时,匹配模式是非贪婪的。非贪婪模式尽量少的匹配所搜索的字符串,而默认的贪婪模式则尽量多的匹配所搜索的字符串。例如,对于字符串 “cs12345”,正则表达式’\d{3,}?’ 将匹配 “123”,而 ‘\d{3,}’ 将匹配 ‘12345’。
^ 匹配输入字符串的开始位置。^的另外一种用法:在方括号表达式中使用(如[^ ]),当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。
2.1 贪婪匹配与非贪婪

当该字符紧跟在任何一个其余限制符 (*, +, ?, {n}, {n,}, {n,m} ) 后面时,匹配模式是非贪婪的。非贪婪模式尽量少的匹配所搜索的字符串,而默认的贪婪模式则尽量多的匹配所搜索的字符串。例如,对于字符串 “cs12345”,正则表达式’\d{3,}?’ 将匹配 “123”,而 ‘\d{3,}’ 将匹配 ‘12345’。

  • 贪婪:匹配字符串时,尽量匹配多的字符串。例如,对于字符串"cs12345"用正则 \d{3,} 匹配时,能够匹配到12345。
    • 语法:默认使用 (*, +, ?, {n}, {n,}, {n,m} ) 时,匹配模式就是贪婪的(尽量多的匹配字符串)。
    • 正则:\d{3,}
    • 正则解释:匹配0-9的数字(\d)最少重复3次以上({3,})(匹配结果为12345)。

  • 非贪婪:匹配字符串时,尽量匹配少的字符串。例如,对于字符串"cs12345"用正则 \d{3,}? 匹配时,能够匹配到123,但匹配不到12345。
    • 语法 使用 (*, +, ?, {n}, {n,}, {n,m} ) 时,在这六个限定符后加上?
    • 正则:\d{3,}
    • 正则解释:匹配0-9的数字(\d)最少重复3次以上({3,})且是非贪婪的(?)(匹配结果为123)。
2.2 否认字符集

匹配输入字符串的开始位置。^的另外一种用法:在方括号表达式中使用(如[^ ]),当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。

和字符集 [ ] 搭配使用,表示不包含在某个字符集的字符。例如,"[^a-z]" 能够匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。

  • 语法:[^]
  • 正则: [^a-z]
  • 正则解释:匹配任何非a-z字母的单个字符。

最后

以上就是我学习时的笔记了,每一个知识点推荐本身写一些案例来进行测试,这样会更容易理解。

若是你想学习Java中正则表达式,请移步:【Java 经常使用类】(7)java.util.regex.Pattern、Matcher的经常使用方法

若是对你有帮助,欢迎点赞,也很是欢迎关注我。

参考

正则表达式百度百科:https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215?fr=aladdin

菜鸟正则表达式教程:https://www.runoob.com/regexp/regexp-tutorial.html(推荐)

learn-regex:https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md

相关

【Java 经常使用类】(7)java.util.regex.Pattern、Matcher的经常使用方法

菜鸟正则表达式在线测试:https://c.runoob.com/front-end/854