由正则表达式如何判断加减乘除括号说开去(g、global 全局参数)

作者:vkvi 来源:ITPOW(原创) 日期:2020-3-14

看看结果吧:

测试结果

完全正确。

就是这个正则表达式太奇葩了,还不如用 indexOf 来判断好理解些。

为什么要加上 (?:){1}?

让我们看看不加的情况,我们将代码简单点,只有 +-。

让我们看看结果:

正则表达式结果

返回 true 总结:

  • 纯 + 不论几个
  • 纯 - 不论几个
  • +-混合只要 + 在前面

也就是说 ^$ 根本没有限制到(它仅仅限制到整个字符串没有其他字符,但是没有限制到 +- 的反复出现),是什么导致 ^$ 没有限制到呢?就是因为 |

| 奇怪的是:

  • 它导致重复匹配。
  • 它居然还管着顺序。

而且 | 还有一个很强大的威力,即假如 | 的某一边为空,则全部返回 true。可以发现 | 与我们常规的理解不一样。

我们想要的是限定长度为 1。所以我们要指定 {1},我们先试试单独限定的情况:

结果如下:

正则表达式结果

更搞不懂了,凭啥第二行代码为 false!到底是哪里造成的呢?仔细看,这里的代码,我们指定了 g。

旧问题还没弄完,新的内容又来了,关于这个 g,我们先放一放,后面说。

于是我们用括号括起来,再作 {1} 限制,现在可以了。

即 ([+]|[-]){1},我们上面呢写得复杂了点,括号里还以 ?: 开头,这表示不要获取括号里面的匹配结果,其实这里加不加都无所谓,因为这里用的是 test,又不是 match、exec

上面的正则表达式有点复杂,为什么不全部用一个 [] 框起来呢?

比如:/^[+-*/()]$/,嗯,这是错误的写法,会报错,错在:+-*,“-”这里有特殊意义——范围,但是“*”的 ASCII 却小于“+”。让我们改改:/^[+\-*/()]$/注意“-”前面有个转义字符“\”。

结果:

正则表达式结果

一切解决了,看起来那么简洁。

现在回过头来说 g 的问题,g 即 global,让我们指定 g 参数试试,其他不变:

正则表达式结果

true 仅剩三个,回到文章一开始那个最复杂的正则表达式,加上参数 g,和这里的结果一模一样。这 g 参数到底惹到哪里了呢?

网上关于 g 的这个解释是:g 决定正则表示是否采用全局匹配。知道什么是废话吗?这就是废话。我来具体写个例子:

第一个正则表达式没有指定 g,第二个指定了 g。效果如下:

正则表达式 global 参数

由此我们知道,这个 g 参数,即 global 表示是否接着刚才的继续查找。

继续了解这个 g 参数中的 lastIndex 变化:

结果如下,我们发现,在第二次 test 时,没有匹配成功,因为换成了 str1,接着从 str2 之前留下的位置找,肯定找不到了,此时 lastIndex 被置为 0。

正则表达式的 lastIndex

进一步总结 lastIndex:

结果是 2、4、6,也就是说 lastIndex 指匹配的尾巴位置,且第 1 个字符使用 1 表示。

所以没事别用 g,以免干扰下一次匹配,除非:

  • 需要接着上次匹配。
  • 不需要接着上次匹配,但是我每次都创建了新的正则表达式对象。

注意:正则表达式的 g(global、全局匹配)参数,在 match 时有不同含义,请参见:JavaScript 正则表达式-s.match(regExp) 获取匹配

相关文章