以语言作类比介绍正则表达式
将正则表达式类比普通的语言
完整的正则表达式由两种字符构成:
元字符: 语法
普通文本字符: 普通语言中的单词
通俗理解: 根据语言的规则,按照语法把单词组合起来,就会得到能传达思想的文本。
思维架构: 完整的正则表达式由小的构建模块单元组成。
元字符
行的起始和结束(匹配位置)
匹配的是一个位置,而不是具体的文本
脱字符号 ^ : 检查一行文本时,代表一行的开始,匹配一行的开始位置
美元符号 $ :检查一行文本时,代表一行的结束,匹配一行的结束位置
Example One:
// 正则表达式
^cat
/*
* ^ 匹配行开头,然后以 c 作为一行的第一个字符,紧接着是一个 a , 紧接着是一个 t 的文本
*/
Example Two:
// 正则表达式
^$
/*
* 匹配的条件是:行开头,然后时行末尾
* 应用意义:**空行** (没有任何字符,包括空白字符)
*/
Example Three:
// 正则表达式
^
/*
* 匹配的条件时:行的开头
* 应用意义: 无意义!!! 因为每一行都有开头,所以每一行都可以匹配 -- 空行也不例外
*/
字符组(匹配若干字符之一)
应用场景: 我们需要搜索的单词是 "grey" ,同时又不确定是否写作 "gray",就可以使用正则表达式结构体[...] (gr[ea]y)。它容许使用者列出某处期望匹配的字符,通常被称作字符组。
// 正则表达式
gr[ea]y
/*
* 在字符组以外,普通字符都有 "接下来是" 的意思。首先匹配 g ,接下来是 r
* 在字符组内部,字符组的内容代表在同一个位置能够匹配的若干字符,所以它的意思是 "或"。此位置字符可以为:e 或 a
*/
字符组内部的连接元字符(-)
- : 连字符表示一个范围: <H[123456]>
等同于 <H[1-6]>
注意:
- 只有在字符组内部,连字符才是元字符,否则就只能匹配普通的连字符号。([a-z]) 表示 此处位置的字符可以是小写字母 a 至 z
- 如果连字符在字符组的开头,代表的也只是一个普通的字符,而不是一个范围。([-az]) 表示此处位置的字符可以是: - 或 a 或 z
排除型字符组(^)
作用: [^ ... ] 替代 [...] , 这个字符组就会匹配一个未列出的字符。字符组中开头的 ^ 表示 "排除"
注意: 排除元字符必须紧挨在 [ 之后,连接元字符 - 紧挨在排除元字符 ^ 之后也算作连接元字符
点号匹配任意一个字符(.)
作用: 元字符 . 是用来匹配任意字符的字符组的简便写法
多选结构
匹配任意子表达式(|)
概念: | 是一个简捷的元字符,它的意思是 或 ,能够把不同的子表达式组合成一个总的表达式,而这个总的表达式又能够匹配任意的子表达式。
注意: | 配合 () 可以限制代表子表达式的界限
grey|gray 等同于 gr(a|e)y , 可以匹配 gray grey
gr[a|e]y 则代表可以匹配: gray gr|y grey
Example:
// 正则表达式
^(From|Subject|Date)::
/*
* 三个多选分支都受括号的限制,所以,这个正则表达式的意思是:匹配一行的起始位置,然后匹配 From 、 Subject 、 Data 中的任意一个,然后匹配 :: , 所以能够匹配的文本是:
* 1) 行起始,然后是 From ,然后是 ::
* 2) 行起始,然后是 Subject,然后是 ::
* 3) 行起始,然后是 Data,然后是 ::
*/
多选结构和字符组的区别
一个字符组只能匹配目标文本中的单个字符
每个多选结构自身都可能是完整的正则表达式,都可以匹配任意长度的文本
可选项
元字符 ? 代表可选项。它只作用于之前紧邻的元素 (单个元素 或 使用 () 限制起来的元素) ,出现的次数为 0 或 1
Example:
// 正则表达式
July? (fourth|4(th)?)
/*
* July? 代表可以匹配: July Jul
* (fourth|4(th)?) 代表可以匹配: fourth 或者 4(th)?
* 4(th)? 代表可以匹配:4 或者 4th
*/
其他量词
+ 表示 之前紧邻的元素 (单个元素 或 使用 () 限制起来的元素) 出现一次或者多次。次数 >= 1
星号 * ,表示之前紧邻的元素 (单个元素 或 使用 () 限制起来的元素) 出现任意多次,或者不出现。 次数 >= 0
区间量词: {a, b},之前紧邻的元素 (单个元素 或 使用 () 限制起来的元素) 出现的次数为[a, b]。可选项 ? 对应的区间量词为: {0, 1}
括号与反向引用
应用基础: 在正则表达式中,() 能够 "记住" 它们包含的子表达式匹配的文本。
应用场景: 穷举所有可能出现的重复单词显然是不可能完成的任务。
- 我们先匹配任意一个单词
- 接下来检查 "后面的单词是否和它一样"
反向引用概念: 反向引用是正则表达式的特性之一,它容许我们匹配与表达式先前部分匹配的同样的文本
反向引用需要与()配合: () 能够记忆其中的子表达式匹配的文本,不论这些文本是什么,元字符序列 \1 都能记住它们。在一个表达式中可以使用多个括号。再用 \1 、 \2、\3 等来表示第一、第二、第三组括号匹配的文本。
Example:
// 正则表达式
([a-z])([0-9])\1\2
/*
* \1 代表[a-z]匹配的内容
* \2 代表[0-9]匹配的内容
*/
神奇的转义(\)
应用场景: 如果需要匹配的某个字符本身就是元字符,则需要使用转义符号 \ 。
- 真正匹配文本中点号 . 号的元序列应该是反斜线加上点号的组合: .,这样的办法适用于所有的元字符,不过在字符组内部无效。
本篇博文学习自《精通正则表达式》,转载请附加原文链接:https://blog.csdn.net/xiaoshengfdyh/article/details/88786833