专栏文章
再谈正则表达式
科技·工程参与者 15已保存评论 15
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 15 条
- 当前快照
- 1 份
- 快照标识符
- @mhz5szms
- 此快照首次捕获于
- 2025/11/15 01:56 4 个月前
- 此快照最后确认于
- 2025/11/29 05:24 3 个月前
-1 为什么要再谈
虽然之前有一篇日报讲正则表达式,但是内容比较深奥且排版不美观,于是决定“再谈”一次。
0 引言:为什么要学习正则表达式
Regex Match Tracer 安装 链接: https://pan.baidu.com/s/13_JR3vzBJw97aP7tQx_6ng 提取码:
lgrbRegex Match Tracer 可以检验正则表达式的正确性。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
使用正则表达式可以用来按一定的方式处理某些字符串。
正则表达式是一种查找以及字符串替换操作。正则表达式在文本编辑器中广泛使用,比如正则表达式被用于:
- 检查文本中是否含有指定的特征词
- 找出文中匹配特征词的位置
- 从文本中提取信息,比如:字符串的子串
- 修改文本
与文本编辑器相似,几乎所有的高级编程语言都支持正则表达式。在这样的语境下,“文本”也就是一个字符串,可以执行的操作都是类似的。一些编程语言(比如 Perl,JavaScript)会检查正则表达式的语法。
1 入门
如果你想在一段文本中查找 ,你可以使用正则表达式
hi。但是,这样的话, 中的 hi 都会被查到,如果你想精确地查询 这个单词,你可以用正则表达式 \bhi\b,这里的 \b 就是正则表达式的一个特殊字符(元字符),代表「单词的分界处」。1.1 元字符
1.2 限定符
*:重复 次或更多次。+:重复 次或更多次。?:重复 次或 次。{n}:重复 次。{n,}:重复 次或更多次。{n,m}:重复 到 次。
1.3 字符集合
[123] 代表匹配 中的任意一个,也可以使用如 [0-9],这个意义是同 \d 一样的。1.4 反义
\W:匹配任意不是字母,数字,下划线,汉字的字符。\S:匹配任意不是空白符的字符。\D:匹配任意非数字的字符。\B:匹配不是单词开头或结束的位置。[^123]:匹配除了 以外的任何字符。
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:重复组号为 的子表达式。
好的,我们来解释一下:比如
\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(还少了字符串匹配中的哪两个元字符?)
当然,这只是为了简便写的,它只能匹配类似于
iakioi2021@iakioi2021.com 这样的网站名与邮箱名相同的邮箱。2.3 贪婪
正则表达式会匹配尽可能多的字符,如
a.*b 就会匹配一个以 开头、 结尾的最长的字符串。当然,如果你想匹配尽可能少的字符,在后面加上一个 ? 即可。2.4 栈
匹配一个字符串,问
<> 是否匹配完整(是否是一个完整的括号序列)需要语法:
(?'Name'):把捕获的内容命名为Name,并压入栈()。(?'-Name'):从栈中压出最后一个压入的名为Name的内容,若不存在,捕获失败。(?(Name)Yes|No):若栈中有一个名为Name的内容,则执行Yes,否则执行No。(?!):直接断言无法匹配(可以类比为 C++ 中的break)。
于是正则表达式:
PLAIN< # 匹配最左边的括号
[^<>]* # 匹配非括号部分
(
(
(?'Stack'<) # 如果匹配到左括号, 压入 "Stack"
[^<>]* # 匹配非括号部分
)+
(
(?'-Stack'>) # 如果匹配到右括号, 弹出 "Stack"
[^<>]* # 匹配非括号部分
)+
)*
(?(Stack)(?!))
>
3 参考资料
- 3.1 正则表达式30分钟入门教程(By deerchao)
- 3.2 正则表达式 - 微软
- 3.3 Github 的文档
相关推荐
评论
共 15 条评论,欢迎与作者交流。
正在加载评论...