标准字符集合

  • 能够与​​多种字符​​匹配的表达式。
  • 注意区分大小写,大写是相反的意思。

还有很多这样的字符,在这里只列出四个:

字符

含义

\d

任意一个数字,0~9中的任意一个

\w

任意一个字母或数字或下划线,也就是AZ,az,0~9,_中任意一个

\s

包括空格、制表符、换行符或空白字符的其中任意一个

.

小数点可以匹配任意一个字符(除了换行符),如果要匹配“\n”在内的所有字符,一般用[\s\S]

例如:

​\d\d\d​​​可以匹配​​123​​​​\d​​可以匹配任意一个数字

自定义字符集合

​[]​​方括号匹配方式,能够匹配方括号中任意一个字符。

表达式

含义

[ab5@]

匹配“a”或“b”或“5”或“@”

[^abc]

匹配"a",“b”,"c"之外的任意一个字符

[f-k]

匹配"f"~"k"之间的任意一个字符

[^A-F0~3]

匹配"A"“F”,"0""3"之外的任意一个字符

  • 正则表达式的特殊符号,被包含到中括号中,则失去特殊意义,除了​​^​​​,​​-​​之外。
  • 标准字符集合,除小数点外,如果被包含于中括号,自定义字符集合将包含该集合。

限定符(量词)

修饰匹配次数的特殊符号。

{n}

匹配重复n次

{n,m}

匹配至少重复n次,最多m次

{m,}

匹配至少m次


匹配表达式0次或1次,相当于{0,1}

+

表达式至少出现1次,相当于{1,}

*

表达式不出现或出现任意次,相当于{0,}

  • 匹配次数中的贪婪模式(匹配字符越多越好,默认)
  • 匹配次数中的非贪婪模式(匹配字符越少越好,修饰匹配次数的特殊符号后再加上一个"?"号)

通过在 ​​*​​​、​​+​​​ 或 ​​?​​​ 限定符之后放置 ​​?​​,该表达式从"贪心"表达式转换为"非贪心"表达式或者最小匹配。

比如你想写一个爬虫,需要用正则表达式去匹配你想要的内容:

<h1>2019happy birthday!</h1>

贪婪模式:​​<.*>​

匹配全部​​<h1>2019happy birthday!</h1>​

非贪婪模式:​​<.*?>​

匹配到了两部分​​<h1>​​​和​​</h1>​

定位符(字符边界)

表达式

含义

^

与字符串开始的地方匹配

$

与字符串结束的地方匹配

\b

匹配一个单词的前边界或后边界

\B

非单词边界匹配

  • ​^​​在中括号中是取反的意思,而在中括号外边就是是匹配字符串的开始地方。
  • (本组标记匹配的不是字符而是位置,符合某种条件的位置)
  • ​\b​​​匹配这样一个位置:前面的字符和后面的字符不全是​​\w​

Ps: 不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ​​^*​​ 之类的表达式。

举个例子:

比如你有如下一堆文本,从上到到下编号为1~4

Chapter
AChapter
ChapterA
AChapterA

​\bChapter​​​可以匹配1、2
​​​\bChapter\b​​​、​​\bChapter$​​​、​​^Chapter$​​​可以匹配1
​​​\BChapter​​​可以匹配2、4
​​​\BChapter\B​​​可以匹配4
​​​^Chapter​​可以匹配1、3(前提:匹配模式为匹配多行模式)

正则表达式的匹配模式

  • IGNORECASE忽略大小写模式
  • SINGLELINE单行模式
  • MULTILINE多行模式

在用某一门语言的正则匹配时,最好还是要去阅读语言自身API

比如在Java中:
​​​Pattern.compile(rexp,Pattern.CASE_INSENSITIVE)​​ 表示表达式整体都忽略大小写。

选择符和分组

用圆括号将所有选项括起来,相邻的选择项之间用​​|​​​分割。
但是圆括号会有一个副作用,使相关的匹配会被缓存(加载到内存中,这可不是个好事情)

表达式

作用

|

左右两边表达式“或”关系,匹配左边或者右边

()

(1).在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰。(2).取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到。(3).每一对括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本

(?:Expression)

一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配的内容,这时可以用非捕获组来抵消使用()带来的副作用

比如说:
原文为(从上到下序号为1~4)

abc
abcabc
abcabcabc
abcabcabcabc

表达式​​(abc)​​​即等于​​abc​​​ 表达式​​(abc){4}​​匹配4
表达式​​(abc){1}​​即等于​​abcabc​​ 表达式​​(abc)*​​匹配整个原文

上边将​​()​​​替换成​​(?:)​​也是可以的,在时间和空间方面,比原来还要好(毕竟不需要存储)。

反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式中从左到右出现的顺序存储。

缓冲区编号从1开始,最多可存储99个捕获的子表达式。每个缓冲区都可以使用​​\n​​​访问,其中​​n​​为一个标识特定缓冲区的一位或两位十进制数。

就拿上边那个abc那个例子来说:

表达式​​(abc)\1​​​等同于​​(abc){2}​​​,即​​abcabc​​​ 表达式​​(abc)\1\1​​等同于​​(abc){3}​​,即​​abcabcabc​

Ps: 这种情况下,用的是​​()​​​表达式,是需要将前边选择的内容缓存下来的。如果换成​​(?:)​​则失效。

学习工具

推荐你使用​​RegexBuddy​​来进行练习正则表达式。