前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正则表达式杂记:入门笔记速查,进阶:组属性,vim magic 与练习场地

正则表达式杂记:入门笔记速查,进阶:组属性,vim magic 与练习场地

作者头像
Piper蛋窝
发布2020-11-19 10:57:31
1.1K0
发布2020-11-19 10:57:31
举报
文章被收录于专栏:Piper蛋窝

前言:提起正则,做深度学习的朋友可能会首先想到防止参数过拟合的 L1/L2 正则算法。此正则非彼正则。 正则表达式(Regular Expression, regex) 用于字符串匹配,规则明确、语法精简、应用场景极其广泛。

几乎所有写代码的朋友都或多或少接触过一点 regex ,但你真的会用吗?比如,用于全匹配 aabc 的 regex 为 ^(?<a>.)\k<a>(?!\k<a>)(?<b>.)(?!\k(b)|\k<a>).$ ,你可以给出解释吗?今天,不妨一起回顾一下 regex 中的知识;此外,笔者将分享一些拓展内容,比如 vim 中的 magic 、练习 regex 的绝佳在线工具等。

入门笔记速查

本段及下段内容是 B站UP主free-coder 视频正则表达式-从入门到group入门[1]的笔记。阅读原文可以观看其视频。 强烈安利这位技术UP。

基础内容

对于字符串abc,我们输入正则表达式:

•abc,可以匹配到出现在任意位置的abc•^abc, 全匹配 ,^a表示这个字符串开头必须是a,c表示这个字符串结尾必须是c

此外,我们可以用 中括号 []某个范围的匹配,比如:

[a-z]表示匹配任意位置的某个字符,这个字符的范围是a,b,c,...,z[a-zA-Z]表示匹配任意位置的某个字符,这个字符的范围是a,b,c,...,z,A,B,C,...,Z

而在中括号[]内,^表示取反,如,^[^a-z]$表示: 全匹配一个字符,这个字符不属于a,b,c,...,z

大括号 表示字符的数量,如:

•^[a-zA-Z]{3}表示,全匹配一个字符串,这个字符串有3个字符,每个字符都属于a,b,c,...,z,A,B,C,...,Z•^[a-zA-Z]{3,}表示,全匹配一个字符串,这个字符串 至少 有3个字符,每个字符都属于a,b,c,...,z,A,B,C,...,Z•^[a-zA-Z]{3,6}

其他符号

.表示除了 回车 的任意符号, 除了 回车/换行符号 line terminators 。

符号 . 匹配到两个字符串,被换行隔开

\d[0-9] 同, \D[^0-9] 同。我们一般用 [\d\D] 表示任意字符, 包括 回车/换行符号 line terminators 。

符号 [\d\D] 匹配到一个字符串,不会受换行影响

\w 是常用互联网命名符号,与 [a-zA-Z0-9_] 同。

\s 是特殊符号,与 [\r\n\t\f\v ] 同,\S 是非特殊符号 [^\r\n\t\f\v ]

此外,还有表示数量的符号:

w?{0,1}w*{0,}w+{1,}

举例:匹配 qq 邮箱

以我的邮箱 piperliu@qq.com 为例:

^[a-zA-Z0-9]\w*第一个字符不能是下划线•后面是@qq\.com$,其中,\.表示字符“.”,\是转义符号。

用 JavaScript 匹配:

代码语言:javascript
复制
'piperliu@qq.com'.match(/^[a-zA-Z0-9]\w*@qq\.com$/)

其中,字符串对象的match()函数中用//包裹正则表达式。

进阶:组属性

组属性很神奇,有了组属性,我们可以表达更复杂的语法规则。

组基础

我们用括号()定义哪些部分是一个组。

代码语言:javascript
复制
'piperliu@qq.com'.match(/^([a-zA-Z0-9]\w*)@qq\.com$/)

其中,我们将piperliu([a-zA-Z0-9]\w*)定义为一个组,且是第1个组。

但是组`([a-zA-Z0-9]\w*)`并不在 JavaScript 对象的组对象 groups 中

如上,在 JavaScript 对象的组对象 groups 中,并没有我们刚刚定义的组。这是因为 groups 中只存放定义了名称的组。我们用 ?<name> 定义组的名称。

代码语言:javascript
复制
'piperliu@qq.com'.match(/^(?<first>[a-zA-Z0-9]\w*)@qq\.com$/)

组`([a-zA-Z0-9]\w*)`在 JavaScript 对象的组对象 groups 中

如上,我们定义组名称为first

组实现引用

在同一个正则表达式中,我们可以直接用索引引用组(\1),也可以用名字引用定义了组名的组(\k<name>)。

组的索引是从 1 开始的,而非 0 , 因为\0已经被用来表示asc码的第一个码。

对于字符串1212,我们可以用如下的方式匹配:

•^\d\d\d\d•^(\d\d)\1,引用第一组•^?<first>(\d\d)\k<first>

组的特殊结构

有了组,我们可以实现很多 Group Construction ,首先以 Positive Lookahead 为例。

对于字符串foobar,fooboo为例,我们想找出foo,且这个foo必须紧紧靠在bar前,则可表达如下:

foo(?=bar)

再举个例子, Positive LookbehindNegative Lookbehind ,对于字符串barfoo,boofoo,我们想找出foo

•这个foo必须紧紧靠在bar后,则(?<=bar)foo•这个foo前紧邻的必须不是bar,则(?!=bar)foo

老师例题

现在想匹配字符串形式aabc,要注意不可以匹配到:

aaaaaabbaaba

则正则表达式如下:

代码语言:javascript
复制
^(?<a>.)\k<a>(?!\k<a>)(?<b>.)(?!\k<b>|\k<a>).$

正确的匹配

分析一下:

^(?<a>.)第一个字符,定义为组a,可以是任何字符.\k<a>第二个字符要与第一个字符同•(?!\k<a>)此外,第二个字符紧后面的字符,不可以是组a的字符•(?<b>.)第三个字符定义为组b(?!\k<b>|\k<a>)此外,第二个字符紧后面的字符,不可以是组b或组a的字符•.第四个字符任意

vim magic

在上古神器 vim 中,我习惯 使用类似正则的思想,进行批量注释 (其实是 VS Code 中 vim 插件,块快捷键 Ctrl+v 与粘贴键有冲突),如下图(编辑模式下:2,3s/^/#/g)。

在第2、3行前加入#,思路是:将开头符号^替换为#

而对于 vim 来讲,在使用 / 正则查找时,分为两个模式:

•magic 模式•nomagic 模式

对于 magic 模式,我们的特殊符号如 . 就是特殊含义(任何字符),即正常的正则表达模式;对于 nomagic 模式,我们的符号都只表达符号本身,使用特殊含义需要用 \ 转义。

:set magic

:set nomagic

更多内容,如 vim 中的 very magic 等,可以参阅:https://www.cnblogs.com/penseur/archive/2011/02/25/1964522.html

学习资源

https://regex101.com/

Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript

如其英文名,极其可靠的在线正则表达式调试工具,汇集了功能包括: 教学、查阅、解析与分析、运算、知识检测等。

感谢你读到最后!我是小拍,一名计算机技术爱好者!觉得文章不错的话,可以点击“在看”支持我一下!有任何批评建议或者合作事宜,可以给我发邮件 piperliu@qq.com[2] ,或者关注公众Piper蛋窝,回复「微信」来加我微信联系~

引用链接

[1] 正则表达式-从入门到group入门: https://www.bilibili.com/video/BV1Rf4y1X7R8 [2] piperliu@qq.com: mailto:piperliu@qq.com

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Piper蛋窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 入门笔记速查
    • 基础内容
      • 其他符号
        • 举例:匹配 qq 邮箱
        • 进阶:组属性
          • 组基础
            • 组实现引用
              • 组的特殊结构
                • 老师例题
                • vim magic
                • 学习资源
                  • 感谢你读到最后!我是小拍,一名计算机技术爱好者!觉得文章不错的话,可以点击“在看”支持我一下!有任何批评建议或者合作事宜,可以给我发邮件 piperliu@qq.com[2] ,或者关注公众Piper蛋窝,回复「微信」来加我微信联系~
                    • 引用链接
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档