正则表达式学习笔记

正则表达式学习笔记

什么是正则表达式 ?

正则表达式是一种被用于从文本中检索符合某些特定模式的文本。

正则表达式是从左到右来匹配一个字符串的。"Regular Expression" 这个词太长了,我们通常使用它的缩写 "regex" 或者 "regexp"。
正则表达式可以被用来替换字符串中的文本、验证表单、基于模式匹配从一个字符串中提取字符串等等。

想象一下,您正在编写应用程序,并且您希望在用户选择用户名时设置规则。我们希望用户名可以包含字母,数字,下划线和连字符。
为了让它看起来不丑,我们还想限制用户名中的字符数量。我们可以使用以下正则表达式来验证用户名

1. 简写字符集

正则表达式为常用的字符集和常用的正则表达式提供了简写。简写字符集如下:

简写描述
.匹配除换行符以外的任意字符
w匹配所有字母和数字的字符: [a-zA-Z0-9_]
W匹配非字母和数字的字符: [^\w]
d匹配数字: [0-9]
D匹配非数字: [^\d]
s匹配空格符: [\t\n\f\r\p{Z}]
S匹配非空格符: [^\s]
b匹配单词的开始或结束
B匹配非单词的开始或结束
^匹配字符串的开始
1匹配除了x意外的任意字符
$匹配字符串的结束

. 匹配除换行符以外的任意字符

image-20200508200933527

w 匹配所有字母和数字的字符: [a-zA-Z0-9_]

image-20200508201638106

W 匹配非字母和数字的字符: [^\w]

d 匹配数字: [0-9]

image-20200508202241226

D 匹配非数字: [^\d]

image-20200508204918965

s 匹配空格符: [\t\n\f\r\p{Z}]

image-20200508202056425

S 匹配非空格符: [^\s]

image-20200508202201805

b 匹配单词的开始或结束

  • 不加b效果

    • image-20200508202605099
  • 加上b的效果

    • 两边都加上b

    image-20200508202648126

    • 前面加上b

    image-20200508203136632

    • 后面加上b

    image-20200508203056898

B 匹配非单词的开始或结束

  • B加前面

image-20200508210556366

  • B加后面

image-20200508210636521

^d+$

  • d+

image-20200508204333501

  • ^d+

image-20200508204512322

  • d+$

image-20200508204528259

  • ^d+$

image-20200508204558902

2 匹配除了good以外的任意字符image-20200508211528319

2.字符转义

正则表达式中使用反斜杠 \ 来转义下一个字符。这将允许你使用保留字符来作为匹配字符 { } [ ] / \ + * . $ ^ | ?。在特殊字符前面加 \,就可以使用它来做匹配字符。
例如正则表达式 . 是用来匹配除了换行符以外的任意字符。现在要在输入字符串中匹配 . 字符,正则表达式 (f|c|m)at\.?,表示: 小写字母 fc 或者 m 后跟小写字母 a,后跟小写字母 t,后跟可选的 . 字符。

3. 元字符

元字符是正则表达式的基本组成元素。元字符在这里跟它通常表达的意思不一样,而是以某种特殊的含义去解释。有些元字符写在方括号内的时候有特殊含义。
元字符如下:

元字符描述
.匹配除换行符以外的任意字符。
[ ]字符类,匹配方括号中包含的任意字符。
3否定字符类。匹配方括号中不包含的任意字符
*匹配前面的子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。
{n,m}花括号,匹配前面字符至少 n 次,但是不超过 m 次。
(xyz)字符组,按照确切的顺序匹配字符xyz。
|分支结构,匹配符号之前的字符或后面的字符。
\转义符,它可以还原元字符原来的含义,允许你匹配保留字符 [ ] ( ) { } . * + ? ^ $ |
^匹配行的开始
$匹配行的结束

.和*和?

  • .*d 匹配以d结尾的字符

image-20200508215058124

  • .d 匹配以d结尾的,并且包含他前面的一个字符

image-20200508215338908

  • .?d 匹配以d结尾的,并且包含他前面的一个字符

image-20200508215406130

  • b.?ldb

image-20200508220659197

  • ^.?ld$

解读:^和$z做字符限定,.?ld表示匹配以ld结尾,前面只能有一个字符

image-20200509090347023

1

  • [abc]ld 匹配ld前面是以a、b、c开头的

image-20200509091014176

  • 4ld 匹配ld前面是非以a、b、c开头的

image-20200509091210913

3.1.重复

以下元字符 +*? 用于指定子模式可以出现多少次。这些元字符在不同情况下的作用不同。

3.1.1 星号

该符号 * 表示匹配上一个匹配规则的零次或多次。正则表达式 a* 表示小写字母 a 可以重复零次或者多次。但是它如果出现在字符集或者字符类之后,它表示整个字符集的重复。
例如正则表达式 [a-z]*,表示: 一行中可以包含任意数量的小写字母。

"[a-z]*" => The car parked in the garage #21.

* 符号可以与元符号 . 用在一起,用来匹配任意字符串 .*。该 * 符号可以与空格符 \s 一起使用,用来匹配一串空格字符。
例如正则表达式 \s*cat\s*,表示: 零个或多个空格,后面跟小写字母 c,再后面跟小写字母 a,再再后面跟小写字母 t,后面再跟零个或多个空格。

"scats" => The fat cat sat on the cat.
3.1.2 加号

该符号 + 匹配上一个字符的一次或多次。例如正则表达式 c.+t,表示: 一个小写字母 c,后跟任意数量的字符,后跟小写字母 t

"c.+t" => The fat cat sat on the mat.
3.1.3 问号

在正则表达式中,元字符 ? 用来表示前一个字符是可选的。该符号匹配前一个字符的零次或一次。
例如正则表达式 [T]?he,表示: 可选的大写字母 T,后面跟小写字母 h,后跟小写字母 e

"[T]he" => The car is parked in the garage.
"[T]?he" => The car is parked in the garage.
例子
  • 0d{2,3}-d{7,8}

image-20200509111007042

tip:我们会发现匹配的第二个号码后面还有个9,那么我们该如何加上限定,不让他匹配后面的呢,就用到了前面学的^和$,来看示例

image-20200509110946231

tip:上面的例子确实匹配到了正确的号码,但真实生活中的例子往往是每个地区的电话号码写法都不一样,看下图示例如何解决image-20200509112321371

ps:上面的例子很多条件放到了一起,不利于阅读,我们可以用分支来解决,符合其中任一一种正则即可,看下图示例

image-20200509112923569

4.分组

将表达式进行做成子集

使用()进行分组

方便match的字符串进行划分

分组的命名:(?<groupname>exp)

(?:exp) 匹配exp,不捕获匹配的文本,也不给分组分配组号

<div\s+class="(?:result|result-op)\s+c-container\s+.*?<a.*?>(?<baiduTitle>.*?)</a>

image-20200509163303405

5.贪婪与懒惰

懒惰

语法说明
*?重复任意次,但尽可能少重复
+?重复一次或更多次,但尽可能少重复
??重复0次或更多次,但尽可能少重复
{n,m}重复n次到m次,但尽可能少重复
{n,}重复n次以上,但尽可能少重复
  • 贪婪

所谓贪婪就是尽可能多的匹配,它遇到第一个b不结束,遇到最后一个b才结束

image-20200509113945988

  • 懒惰

遇到个b就匹配成功

image-20200509114228281

6.处理选项

语法说明
IgnoreCase匹配时不区分大小写
Multiline更改^和$的含义,是它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确的含义是:匹配n之前的位置以及字符串结束前的位置)
Singleline更改.的含义,使它与每一个字符匹配(包括换行符n)
IgnorePatternWhitespace忽略表达式中的非转义空白并启用由#标记的注释
ExplicitCapture仅捕获已被显式命名的组

7.反向引用

匹配taobao taobao,home home 这样的情况

b(w+)bs+1b

b(?<Word>w+)bs+k<Word>b 命名后的写法

例一:

\b(\w+)\b\s+\1\s+\1

image-20200509203117776

8.零宽断言

正向零宽断言

?=exp 零宽度正预测先行断言,自身出现的位置的后面能匹配表达式

exp

\b\w+(?=ing\b)

image-20200509190747889

零宽度正回顾后发断言

?<=exp 零宽度正回顾后发断言,自身出现的位置的前面能匹配表达式

exp

<?<=\bre>\w+\b

image-20200509191003290

负向零宽断言

查找这样的单词,它里面出现了字母q,但q后面跟的不是字母u

不用断言的方式

\b\w*q[^]\w*\b

image-20200509190038301

使用断言 不消费任何字符

例一:

\b\w*q(!u)\w\b

image-20200509185934605

例二:前面三位是数字,后面不能是数字

\d{3}(?!\d)

image-20200509195248044

零宽度负回顾后发断言

例一:前面不是小写字母的7位数字

(?<![a-z])\d{7}

image-20200509201245152

断言综合示例

例一:找出所有个位数

(?<=\s+)\d(?=\s+)|(?<!\d)\d(?!\d)

image-20200509203808715


  1. x
  2. good
  3. abc
Last modification:August 4th, 2020 at 04:21 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment