再谈正则表达式
-1 为什么要再谈
虽然之前有一篇日报讲正则表达式,但是内容比较深奥且排版不美观,于是决定“再谈”一次。
0 引言:为什么要学习正则表达式
Regex Match Tracer 安装 链接: https://pan.baidu.com/s/13_JR3vzBJw97aP7tQx_6ng 提取码: lgrb
Regex Match Tracer 可以检验正则表达式的正确性。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
使用正则表达式可以用来按一定的方式处理某些字符串。
正则表达式是一种查找以及字符串替换操作。正则表达式在文本编辑器中广泛使用,比如正则表达式被用于:
- 检查文本中是否含有指定的特征词
- 找出文中匹配特征词的位置
- 从文本中提取信息,比如:字符串的子串
- 修改文本
与文本编辑器相似,几乎所有的高级编程语言都支持正则表达式。在这样的语境下,“文本”也就是一个字符串,可以执行的操作都是类似的。一些编程语言(比如 Perl,JavaScript)会检查正则表达式的语法。
1 入门
如果你想在一段文本中查找 hi
。但是,这样的话,hi
都会被查到,如果你想精确地查询 \bhi\b
,这里的 \b
就是正则表达式的一个特殊字符(元字符),代表「单词的分界处」。
1.1 元字符
由于某些原因,你不得不在云剪贴板查看此内容 /kel
1.2 限定符
*
:重复0 次或更多次。+
:重复1 次或更多次。?
:重复0 次或1 次。{n}
:重复n 次。{n,}
:重复n 次或更多次。{n,m}
:重复n 到m 次。
1.3 字符集合
[123]
代表匹配 [0-9]
,这个意义是同 \d
一样的。
1.4 反义
\W
:匹配任意不是字母,数字,下划线,汉字的字符。\S
:匹配任意不是空白符的字符。\D
:匹配任意非数字的字符。\B
:匹配不是单词开头或结束的位置。[^123]
:匹配除了\tt 1,2,3 以外的任何字符。
2 进阶
2.1 后向引用
使用 ()
框住一个子表达式后,该表达式会有一个编号(从 \组号
的形式重复编号为 组号
的子表达式。
(exp)
:匹配exp
,并自动分组。(?<Name>exp)
:匹配exp
,并命名为Name
,重复可用\k<Name>
。(?:exp)
:匹配exp
,但不捕获匹配的文本,也不给此分组分配组号。(?=exp)
:匹配exp
前面的位置。(?<=exp)
:匹配exp
后面的位置。(?!exp)
:匹配exp
后面的不是exp
的位置。(?<!exp)
:匹配exp
前面的不是exp
的位置。(?#note)
:这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读。\n
:重复组号为n 的子表达式。
好的,我们来解释一下:比如 \b\w+(?=ing)
会匹配一个单词中 He is playing computer and coding.
中会匹配到
此外,对于 \n
的应用,我也举个例子:匹配四个相同的英语单词,可以使用以下代码:\b([a-z]+) \1 \1 \1\b
。其中 \1
指的是子表达式 [a-z]+
。
2.2 实践
请匹配一个合法邮箱,合法邮箱满足:
- 第一部分,由若干个字符组成(包括
a-z,A-Z,0-9
)。 - 第二部分,由一个
@
组成。 - 第三部分,由网站名组成,网站名由若干个字符组成(包括
a-z,A-Z,0-9
),后缀可用.com
。
示例如:\b([a-zA-Z0-9]+)@\1\.com\b
(还少了字符串匹配中的哪两个元字符?)
当然,这只是为了简便写的,它只能匹配类似于 [email protected]
这样的网站名与邮箱名相同的邮箱。
2.3 贪婪
正则表达式会匹配尽可能多的字符,如 a.*b
就会匹配一个以 ?
即可。
2.4 栈
匹配一个字符串,问 <>
是否匹配完整(是否是一个完整的括号序列)
需要语法:
(?'Name')
:把捕获的内容命名为Name
,并压入栈(\bf{Stack} )。(?'-Name')
:从栈中压出最后一个压入的名为Name
的内容,若不存在,捕获失败。(?(Name)Yes|No)
:若栈中有一个名为Name
的内容,则执行Yes
,否则执行No
。(?!)
:直接断言无法匹配(可以类比为 C++ 中的break
)。
于是正则表达式:
< # 匹配最左边的括号
[^<>]* # 匹配非括号部分
(
(
(?'Stack'<) # 如果匹配到左括号, 压入 "Stack"
[^<>]* # 匹配非括号部分
)+
(
(?'-Stack'>) # 如果匹配到右括号, 弹出 "Stack"
[^<>]* # 匹配非括号部分
)+
)*
(?(Stack)(?!))
>
3 参考资料
- 3.1 正则表达式30分钟入门教程(By deerchao)
- 3.2 正则表达式 - 微软
- 3.3 Github 的文档