美文网首页
不积跬步之第五章--正则的拆分

不积跬步之第五章--正则的拆分

作者: 雨飞飞雨 | 来源:发表于2021-06-17 08:47 被阅读0次

对于一门语言的掌握程序怎么样?可以有两个角度来衡量:读和写。不仅要求自己能解决问题,还要能看懂别人的解决方案,代码是这样,正在表达式也是这样。

正则这门语言跟其他语言有一点不同,它通常就是一大堆字符,而没有所谓“语句”的概念。 如何能正确地把一大串正则拆分成一块一块的,成为了破解“天书”的关键。

这篇文章提供的答案:

  • 结构和操作符的优先级 ?

结构和操作符

编程语言一般都有操作符。只要有操作符,就会出现一个问题。当一大堆操作在一起时,先操作谁,又后操 作谁呢?为了不产生歧义,就需要语言本身定义好操作顺序,即所谓的优先级。

而在正则表达式中,操作符都体现在结构中,即由特殊字符和普通字符所代表的一个个特殊整体。

JavaScript 正则表达式中,都有哪些结构呢?
字符字面量、字符组、量词、锚、分组、选择分支、反向引用。
具体含义简要回顾如下:

结构 说明
字面量 匹配一个具体字符,包括不用转义的和需要转义的。比如 a 匹配字符 "a", 又比如 \n 匹配换行符,又比如 . 匹配小数点。
字符组 匹配一个字符,可以是多种可能之一,比如[0-9],表示匹配一个数字。也有\d的简写形式。另外还有反义字符组,表示可以是除了特定字符之外任何一个字符,比如[^0-9]。表格一个非数字字符,也有\D的简写形式。
量词 表格一个字符连续出现,比如a{1,3}表示,"a"字符连续出现3次。另外还有常见的简写形式,比如a+表示"a"字符连续出现至少一次。
匹配一个位置,而不是字符,比如^匹配字符串的开头,又比如\b匹配单词边界。又比如(?=\d)表示数字前面的位置。
分组 用括号表示一个整体,比如(ab)+表示ab两个字符连续出现多次,也可以使用非捕获分组,(?:ab)。反向引用,比如\2表示引用第二个分组
分支 多个子表达式多选一,比如`abc bcd,表达式匹配abc或者bcd`字符子串。

而其中涉及到的操作符有:

操作符描述 操作符 优先级
转义符 \ 1
括号和方括号 (…)(?:…)(?=…)(?!…)[…] 2
量词限定符 {m}{m,n}{m,}?*+ 3
位置和序列 ^$\元字符一般字符 4
管道符(竖杠) ` ` 5

上面操作符的优先级从上至下,由高到低。

下面拆分一个例子:
/ab?(c|de*)+|fg/

  1. 由于括号的存在,所以,(c|de*)是一个整体。
  2. 在其中,由于管道符的存在,里面是一个分支结构。所以c是一个整体,de*是一个整体
  3. de*中由于量词的存在,所以e是一个整体
  4. 同理,整个正则分成了ab?(c|de*)+fg
  5. 由于分支的存在,又整体分为 ab?(c|de*)+fg两个部分。
image.png

注意要点:

关于结构和操作符,还是有几点需要强调:

1.匹配字符串整体问题

因为是要匹配整个字符串,我们经常会在正则前后添加^$

例如要匹配abc或者bcd,如果不小心就可能写成/^abc|bcd$/.

但是位置字符和字符序列优先级要比竖杠高,故其匹配的结构是:


image.png

所以我们这里要写成这样/^(abc|bcd)$/.

image.png

可以看出两个的差距。

2.量词连缀问题

假设,要匹配这样的字符串:

  1. 每个字符为a,b,c任选其一。
  2. 字符串的长度是3的倍数。

此时正则不能想当然地写成/^[abc]{3}+/.因为它会报错。

image.png

怎么办呢?

给它加个括号,把前面括起来。

image.png

3.元字符转义问题

所谓元字符,就是正则中有特殊含义的字符。

所有结构,用到的元字符总结如下:

^、$、.、*、+、?、|、\、/、(、)、[、]、{、}、=、!、:、- ,

当匹配上面的字符本身时,可以一律转义:

var string = "^$.*+?|\\/[]{}=!:-,";
var regex = /\^\$\.\*\+\?\|\\\/\[\]\{\}\=\!\:\-\,/;
console.log( regex.test(string) );
// => true

其中string中的\字符也是要转义的。

另外,在string中,可以把每个字符转义,当然,转义后的结构仍是本身:

var string = "^$.*+?|\\/[]{}=!:-,";
var string2 = "\^\$\.\*\+\?\|\\\/\[\]\{\}\=\!\:\-\,";
console.log( string == string2 );
// => true

4.字符串中的元字符

更字符组相关的元字符,如果需要匹配,也需要进行转义。

var string = "^$.*+?|\\/[]{}=!:-,";
var regex = /[\^$.*+?|\\/\[\]{}=!:\-,]/g;
console.log( string.match(regex) );
// => ["^", "$", ".", "*", "+", "?", "|", "\", "/", "[", "]", "{", "}", "=", "!", ":",
"-", ","]

5.匹配[abc]{3,5}

如果要匹配[abc]{3,5}.

可以写成/\[abc]/或者/\[abc]/.

var string = "[abc]";
var regex = /\[abc]/g;
console.log( string.match(regex)[0] );
// => "[abc]"

只需要转义第一个方括号就可以,因为后面的构不成字符组。

而匹配{3,5}则使用/\{3,5}/.

6.其余情况

比如=,!,:,-,,等符号,只要不在特殊结构中,并不需要转义。

但是,括号需要前后都转义/\(123)/

至于剩下的 ^、$、.、*、+、?、|、\、/等字符,只要不在字符组内,都需要转义的。

相关文章

  • 不积跬步之第五章--正则的拆分

    对于一门语言的掌握程序怎么样?可以有两个角度来衡量:读和写。不仅要求自己能解决问题,还要能看懂别人的解决方案,代码...

  • 不积跬步之正则的终章整理

    终于学习完了这一本《JavaScript正则表达式迷你书》,全书只有八十多页,而我却差不多学习了两周时间。从不熟悉...

  • 不积跬步

    2018/10/25 星期四 晴 没想到二姐的高价小收音机比手机的辐射要强,放在床边睡觉,...

  • 不积跬步

    “不积跬步无以至千里”常用来激励。 可在自己身上发掘这句名言,却只有垃圾、肥肉和慢。 一个上午,断断续续收拾了两个...

  • 不积跬步

    生活中看起不起眼的事情,对一些人来说就是财富机遇 朋友在我们单位上班,也属于从别的单位挖过来的,老板慧眼识珠,两人...

  • 点滴积累成就精彩演讲

    冰冻三尺,非一日之寒。 ——王充不积跬步,无以...

  • 不积跬步之快速排序

    快速排序使用了分治思想来实现。 和冒泡排序一样,快速排序也属于交换排序,通过元素直接的比较和交换位置来达到排序的目...

  • 不积跬步之选择排序

    选择排序 假如我们有一组歌的数据,我们需要按照播放量从大往小排序。最简单的做法就是,先从这组数据里找到最大的那个,...

  • 先让孩子“完成一个小目标”

    不积跬步,无以至千里;不积小流,无以成江海。 ——荀子《劝学篇》 做父母的都有望子成龙之...

  • 晨间日记

    不登高山,不知天之高也; 不临深溪,不知地之厚也。 不积跬步,无以至千里; 不积小流,无以成江海。 ​​​

网友评论

      本文标题:不积跬步之第五章--正则的拆分

      本文链接:https://www.haomeiwen.com/subject/yshxyltx.html