正则表达式基础


今天看了一下正则表达式,早就看这东西不顺眼了,以前也是看过一些基础语法,可惜时间长了,也没有动手写过,都给忘了,好记性不如烂笔头,还是要做好笔记啊!

啥是正则表达式?

  • 正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
  • 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
    说白了,这玩意就是一个用来匹配字符串的工具,它十分灵活,用好了轻则提升工作效率,重则轻轻松松上王者。

从示例开始

最简单的正则表达式就是要匹配的字符本身,比如我要匹配man这个单词,就可以用man这个正则表达式。但是这样没啥意思,索然无味。下面看一个简单的正则表达式

hello\s\d+

它可以匹配hello 123,也可以匹配hello 153212,怎么样,是不是真香!

元字符

这个元字符不必纠结是啥,他就跟Java的关键字类似,规定的特殊意义的字符。元字符按照我自己的理解大概可以分为以下三类:

  • 特殊字符:比如空格,制表符,回车,换行等。
  • 限定字符:指定正则表达式的一个给定组件必须要出现多少次才能满足匹。
  • 定位符:描述字符串或单词的边界。

特殊字符

特殊字符意义怎么记忆
\n匹配一个换行符new line
\f匹配一个换页符form feed
\r匹配一个回车符retrun
\s匹配一个空格符space
\d匹配一个数字digit
\w匹配一个包括下划线在内的任意字符word
\t匹配一个制表符tabtab
\v匹配一个垂直制表符vertical tab
[\b]匹配一个回退符backspace,使用[]符号是避免和\b重复
.匹配除换行符 \n 之外的任何单字符点生万物
[标记一个中括号表达式的开始。就是括号的意思,小括号已经被子表达式占了
\常用于转义,当需要匹配的字符属于元字符时,就需要转义转义
I用于表示正则表达式的逻辑或逻辑或

限定字符

字符意义怎么记忆
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。宇宙洪荒,辰宿列张:宇宙伊始,从无到有,最后星宿布满星空
+匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。1+加一
?匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}。问号,有还是无?
{n}n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。可以想象成一个数轴,从一个点,到一个射线再到线段。n和m分别表示了左闭右闭区间的左界和右界
{n,}n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。

定位符

字符意义怎么记忆
\b单词的开始或结尾bianjie
\B非单词的开始或结尾大写表示造反
^待匹配的字符串的开头小荷才露尖尖角
$待匹配的字符串的结尾有点终结者的感觉

示例分析

看完了基础常用的元字符,让我们来搞一波分析,加深记忆

  • 例一:匹配正整数
^[1-9]\d*$

^$ 分别代表匹配字符串的开头和结尾,这个没的说,[1-9]\d表示匹配数字1到9,*表示0次或任意次。

  • 例二:电话号码,例如(010)88886666,或022-22334455
\(?0\d{2}[) -]?\d{8}

=(?0\d{2}= 先把左括号(转义,它能出现一次或零次,然后是一个0,在后面是两个数字。==[) -]?==表示零次或一次的 “)-”,后面是八个数字

高段位用法

分组(子表达式)

所有以(和)元字符所包含的正则表达式被分为一组,每一个分组都是一个子表达式,它也是构成高级正则表达式的基础。如果只是使用简单的(regex)匹配语法本质上和不分组是一样的,如果要发挥它强大的作用,往往要结合回溯引用的方式。

回溯引用

所谓回溯引用(backreference)指的是模式的后面部分引用前面已经匹配到的子字符串。你可以把它想象成是变量,回溯引用的语法像\1,\2,…,其中\1表示引用的第一个子表达式,\2表示引用的第二个子表达式,以此类推。而\0则表示整个表达式。一个很经典的例子:

查找文本中两个相同的相邻单词
 I am am  a happy coder coder
 可以用下面的正则表达式来匹配它
\b([a-z]+)\s\1\b

开头和结尾的 元字符限定的连续单词的开头和结尾,子表达式==(a-z+)==表示匹配一个或多个小写字母,\s表示一个空格符,\1 表示引用第一个子表达式,匹配的结果是 “ am am coder coder”

前向查找

前向查找(lookahead)是用来限制后缀的。凡是以(?=regex)包含的子表达式在匹配过程中都会用来限制前面的表达式的匹配。例如happy happily这两个单词,我想获得以happ开头的副词,那么就可以使用happ(?=ily)来匹配。如果我想过滤所有以happ开头的副词,那么也可以采用负前向查找的正则happ(?!ily),就会匹配到happy单词的happ前缀。

后向查找

介绍完前向查找,接着我们再来介绍一下它的反向操作:后向查找(lookbehind)。后向查找(lookbehind)是通过指定一个子表达式,然后从符合这个子表达式的位置出发开始查找符合规则的字串。举个简单的例子: apple和people都包含ple这个后缀,那么如果我只想找到apple的ple,该怎么做呢?我们可以通过限制app这个前缀,就能唯一确定ple这个单词了。

/(?<=app)ple/

其中(?<=regex)的语法就是我们这里要介绍的后向查找。regex指代的子表达式会作为限制项进行匹配,匹配到这个子表达式后,就会继续向后查找。另外一种限制匹配是利用(?<!regex) 语法,这里称为负后向查找。与正前向查找不同的是,被指定的子表达式不能被匹配到。于是,在上面的例子中,如果想要查找apple的ple也可以这么写成
/(?<!peo)ple。

部分内容参考:https://juejin.im/post/5cdcd42551882568651554e6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值