正则表达式匹配空值_正则表达式学习笔记(三):元字符

本文是正则表达式的学习笔记,重点介绍了如何使用元字符匹配空值,包括多选分支、忽略大小写、单词分界符和量词的应用等关键概念,帮助读者深入理解正则表达式。
摘要由CSDN通过智能技术生成

前言

上一篇文章中我们研究了行的起止符、字符组和点号等正则表达式的元字符,有的同学可能注意到,在第一篇学习笔记中提到的(.*?)正则表达式的含义还是不明朗,因为*?这两个符号到目前为止,我们还没有分析过。 这一篇文章中,我们继续来研究其它的元字符,之后用学到的知识来给(.*?)做出解释。

多选分支

我们已经知道字符组是由中括号[]括起来的,而多选结构则是由小括号()括起来的,从匹配字符的数量来看,字符组相当于多选结构的特殊形式,因为字符组提供了单个字符的备选匹配,事实上,多选结构也可以完成单个字符的备选匹配,只不过需要在备选的字符之间用|进行分割,下面给出Perl代码演示:
$value = 'Hello world! Hella world!';while ($value =~ m/Hell(o|a)/){    print "匹配到的字符:$& \n";    $value = $'}
在上述代码中, (o|a) 就是所谓的多选结构,它可以用字符组 [oa] 代替,对它运行的结果如下:

987802d901aa19ca9a1bbd45b7baf141.png

和字符组不同的是,多选结构可以容纳更多字符的备选,将上面例子中的正则表达式修改为Hel(lo|la),同样可以匹配到一样的结果,我们用Python来实现如下:

d97b8cf0b7afefc501929e642de55547.png

忽略大小写

在匹配字符串的时候,有时我们是需要忽略大小写的,比如给出的字符串是Hello world! Hella world!,若我们所写的正则表达式hell(o|a)需要对该字符串进行匹配,就需要用到忽略大小写开关,在Perl中是这样写的:
$value = 'Hello world! Hella world!';while ($value =~ m/hel(lo|la)/i){    print "匹配到的字符:$& \n";    $value = $'}
上述代码中的 i 即是忽略大小写的开关,运行代码如下:

a1cdef8e7b194465f8d3748380968da3.png

Python中,忽略大小写的开关是添加flags=re.IGNORECASE,代码如下:

bb3339184de562a60f3066559442b796.png

单词分界符

在英文中,单词是以空格进行区分的,这就牵扯到单词的分界符问题,在Perl中,单词的分界符是\b,将要匹配的字符串放在两个\b之间,就意味着必须要对一个单词进行匹配,示例如下:
$value = 'Hello world! Helloo world! Hella world!';while ($value =~ m/\bhel(lo|la)\b/i){    print "匹配到的字符:$& \n";    $value = $'}
在上述代码中,我们添加了一些单词,当正则表达式中不含单词定界符时,它会输出三个结果,但加上定界符后,运行结果只有两个字符串,如下图所示:

0e4498f1c240b4f449ac95bb2deeec35.png

Python中的单词定界符也是\b,但要注意,当为正则表达式添加\b时,该字符串前要添加r字母,r的意思是保持字符串的原生态,这样转义字符就会保持原来的意义:

ce048fcd6975738cb323cba87dfc8e9f.png

量词的应用

所谓的量词指的是在正则表达式中出现的字符应该重复的次数,一般我们有三个量词符号,分别是?+*,它们的表示次数如下图所示:

ef52bb8fb047955b522065f16cbca71f.png

比如我们有这样一个字符串: Hello world! hell world! ,现在我察觉到其中一个 hello 少写了一个 o ,但它确实应该是 hello ,因此需要将所有应该是 hello 的字样找到,这时需要用到 ? 量词:
$value = 'Hello world! hell world!';while ($value =~ m/\bhello?\b/i){    print "匹配到的字符:$& \n";    $value = $'}
执行结果如下:

1553eb429239a55859cb4d01d512d622.png

再来看一下+的用法,现给出一字符串H1 H12 H123 H566 H H78,要将该字符串中H后面至少带一位数字的单词找出来,用Perl代码应该这样写:
$value = 'H1 H12 H123 H566 HR2 H H78';while ($value =~ m/\bH[0-9]+\b/i){    print "匹配到的字符:$& \n";    $value = $'}

8991d2bc299daf2eb4360bcfa39001db.png

从上述输出结果来看,给定字符串中的HR2H没有匹配到,这符合我们的要求,如果我们需要将首字母是H开头的单词找出来,哪怕只有一个H字母也要搜索到,则应该这样写代码:
$value = 'H1 H12 H123 H566 HR2 H H78';while ($value =~ m/\bH[0-9A-Za-z]*\b/i){    print "匹配到的字符:$& \n";    $value = $'}

dc13d03d2b418f05d3d6fb88dd29afc3.png

好了,到目前为止,我们已经学完了第一篇文章中提到的那个正则表达式m/^hello (.+?)$/i中所有的信息,现在可以来解释一下它所表达的意思:m/.../Perl专用的表示正则表达式的格式,i是忽略大小写,^是行起首,$是行结尾,hello是进行原字符串匹配,(.+?)是一个字符组,它里面的.表示任意字符,紧随其后的+是指这个字符至少要匹配一次,而再随其后的?则是指前面的那个字符最多可重复1次,按这样的解释,我们来对下面一些字符串测试一下匹配效果,以下用Python测试:

71250fe237719c5284994f94119d338c.png

从上面的测试结果可以看出,(.+?)这个正则表达式可以匹配一个空格,也可以匹配任意长度的字串。这样看起来,它与(.*)应该是一样的,但却有以下区别:

70014af59de4e88e9281ccb84baa1f3d.png

从上面对比可以看出,(.+?)在无法遇到一个字符时,它返回一个空值,但(.*)即使无法遇到字符,它也会返回一个空字符串。这一点值得注意。Perl语言中有同样的情况,即对于Hello 而言,'^hello (.+?)$'无法匹配到任何字符,匹配失败,但'^hello (.*)$'会匹配到一个空字符,匹配成功。 对这个问题的解释是这样的:.+本身确保了该位置至少要有一个字符,而其后的?只是说明该字符存在0次还是1次,当一个字符都没有时,.+就匹配失败了,?无法发挥作用;.*的意思则是该位置可以有字符也可以没有字符,当没有字符时,显示空字符。 另一点要注意的是,尽管正则表达式只有(.+?),但它是一个字符一个字符连续进行匹配的,因此可以一直匹配到行尾。

小结

本文继续对正则表达式中的元字符进行了分析研究,并对第一篇学习笔记中的正则表达式含义进行了解释。从测试结果来看,同学们应该能感觉到正则表达式功能的强大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值