正则中的不匹配

同事提出了一个需求,匹配1|1,但是有不能匹配-1|1,也就是1|1之前不能有-
代码如下

const reg = /[^-]1\|1/
reg.test("1|1")	// true
reg.test("-1|1") // false
reg.test("-1111|1")	// true

由此我和我的小伙伴们又去找了些其他奇奇怪怪的需求~比如

// 相邻两个数字不重复
const siblingNum = /(\d)\1/	// 这个是找到相邻数字重复的情况,
siblingNum.test("112")	// true, 取反就是false,也就是没有找到相邻数字重复的情况

// 所有的数字不重复
const noRepeat = /^(?:(\d)(?!.*?\1))+$/;
noRepeat.test("123")	// true
noRepeat.test("1231")	// false

在这里面知识点还挺多。

  1. 对于^的使用,我一直认为他是起始符,没想到他还有第二个作用,[ ^abc ]:负值字符集合。匹配未包含的任意字符。可以匹配abc以外的字符

  2. \1,知识不足的我原以为只有在匹配结果中才能用$1来取到第一个括号里的数据,现在才知道在正则表达式中可以使用\1来取出第一个括号中的数据,这里需要注意一点是第一个括号。
    比如/(\d)\1//((\d)\1)/这两个是完全不一样的,第一个里面第一个括号包含的只有\d,而第二个则是(\d)\1,所以运行结果也是不一样的,
    第二种我也不知道她能匹配啥,我对他的理解应该是一个错误写法,因为\1取出来的是包含\1的,所以会是一个循环嵌套,感觉应该是出错的,希望有人能帮帮我~

  3. ?: 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。
    例子:上面/((\d)\1)/想改造成/(\d)\1/的结果,可以这么写:/(?:(\d)\1)/ 这样表达式就不会匹配最外面那个括号了,第一个括号就变成\d外面的括号了,这样就跟/(\d)\1/一样了。

  4. ?! 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

    先提供一下别人的例子
    例如"Windows(?!95|98|NT|2000)“能匹配"Windows3.1"中的"Windows”,但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

    根据我的实验,我对他的理解是这样的:(还是基于上面的例子)
    他只能匹配Windows后面不是95|98|NT|2000的字符串中的Windows字段
    在这里插入图片描述
    对于(?!.*?\1)这一段表达式,我想把他拆开看,首先是?!,然后是.*,并对他进行?处理,也就是可有可无,最后是\1,也就是应对前面的(\d)。
    先看后面的 .*?\1,这一块应该是匹配当前元素之前所有的可匹配的字符,例如123451,(\d)(.*?\1),匹配的应该就是123451,\d先匹配到1,然后\1就代表了1,然后.*?就代表了2345。
    然后在加上?!,也就是说不匹配后面再次出现当前字符的情况,如果没有出现,当前字符才算匹配成功。

以上就是我对正则的一点理解,记下来,以防后面忘记,如果有哪里写错了,请大家尽情的鞭挞我吧~感谢^_^

参考文献:
https://www.runoob.com/regexp/regexp-metachar.html
https://www.cnblogs.com/youxin/p/3546657.html
https://www.cnblogs.com/dogecheng/p/11466687.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值