正则表达式位置匹配总结


前言

关于正则表达式位置匹配的文章有很多,以下为笔者学习过程中的总结


1、位置匹配知多少?

在正则表达式中和位置有直接或间接关系的有,修饰符 “m” “y”,锚点,边界词\b,反向引用\N,前瞻断言与后瞻断言,正则表达式和字符串的方法,如:search,match,replace,exec等都能和位置下标扯上关系。

2、锚点与边界词\b

插入符号 ^ 表示匹配输入的开头
美元符号 $ 表示匹配输入的结尾

// 示例
const str = "Singh handsome";
// 表示开头为S
/^S.*/.test(str1) // true
// 表示结尾为e
/.*e$/.test(str1) // true

插入符号 ^ 要放在模式的开头,美元符号 $ 要放在模式的结尾
锚点既可以用做单一字符类也可以用做分组和集合范围

锚点与修饰符 “m”

修饰符 “m” 表示多行搜索,也就是每一行的开头和结尾都会匹配到

const str = `Singh 
hand
Some`;
str.match(/^S.*/gm)  // ['Singh ', 'Some']

当然对于简单的开头/结尾我们可以使用 startsWith/endsWith 方法就好了

3.边界词\b与反向引用\N

边界词\b不是[\b]哦,[\b]表示一个退格倒也能和位置扯上一点关系。
从MDN的解释来看 一个词的边界就是一个词不被另外一个“字”字符跟随的位置
如果你认为空格就是边界词的话这是不完全正确的理解

const str = "Singh hand some";

这里有几个边界词呢 答案是6个

const str = "Singh hand some";
str.match(/\b/g)
(6) ['', '', '', '', '', '']

边界指的是就是位置,这6个位置分别是
在这里插入图片描述
没错,边界的理解就是一个\w的另一边不是\w,那么说明它在边界

反向引用 \N

在讲解反向引用怎么用之前,先来论述一下反向引用和位置的关系
反向引用是指当我们匹配到一个模式后开始,直到下一次匹配到该模式的之间内容(位置)
反向引用是开始和结束的匹配关系
让我们来看一个例子

const str = `I said "you can't have both"`;

这里我想要匹配的是由 双引号 " 开头 并且由 双引号 " 结尾区间的内容
或者是单引号 ’ 开头结尾之间的内容

const reg = /["'](.*?)["']/g;

这样匹配到的是 you can
因为这既可以是双引号也可以是单引号
为了保证开头模式和结尾模式相同,我们可以使用反向引用

const reg = /(["'])(.*?)\1/g;

这里的 \1 是分组的序号,可以是\1 \2 \3 …\N,根据分组规则选择你希望匹配的第几个分组既可,其核心目的在于引用之前的分组,划定一块相同模式区间的内容。
你也可以通过给捕获组具名的方式,具名反向引用,通过\k 表示

const reg = /(?<yname>["'])(.*?)\k<yname>/g;

4、前瞻断言与后瞻断言

有的时候我们需要将一个 “模式” 必须匹配在另一个"模式"之前或者之后的位置,这个时候可以使用前瞻后瞻断言。
前瞻断言:X(?=Y)
后瞻断言:(?<=Y)X
这里的X表着断言之前(之后)的模式,Y代表以及用于断言的模式,只有两个模式都匹配上了,才能通过正则。

前瞻断言

const str = "1 turkey costs 30%"

这里我想匹配的是数字后面跟着%的数字

str.match(/\d+(?=%)/)
['30', index: 15, input: '1 turkey costs 30%', groups: undefined]

呼应一下上面说的 只有两个模式都匹配上了,才能通过正则。
这里的 X = \d+, Y = (?=$)

前瞻断言和后瞻断言括号中的内容不会成为结果的一部分,如果我们希望 % 也在结果中可以通过一个而外的括号来包裹

str.match(/\d+(?=(%))/)
['30', '%', index: 15, input: '1 turkey costs 30%', groups: undefined]

断言也分为肯定和否定
前瞻否定断言:X(?!Y)
后瞻否定断言:(?<!Y)X

比如上面这里数字后面不跟着 %

str.match(/\d+(?!%)/)
['1', index: 0, input: '1 turkey costs 30%', groups: undefined]
后瞻断言

后瞻和前瞻是一样的,只不过他在反方向上进行条件判断

const str = "1 turkey costs %30"
这里我想匹配的是数字前面带有 % 的数字

str.match(/(?<=%)\d+/)
['30', index: 16, input: '1 turkey costs %30', groups: undefined]

// 后瞻否定写法
str.match(/(?<!=%)\d+/)

最后通过一个前瞻断言实现数字千分位来总结一下

/(\d)(?=(\d{3})+$)/g

这里我理解的是 正则表达式内建引擎一旦满足了匹配结果,就会忽略已经匹配的所有内容,并尝试跟多的匹配

str.match(/\d(?=(\d{3})+$)/g)
(3) ['1', '4', '7']

按照这个理论 第一个匹配到的是 7 然后忽视7及7之前的内容,然后到 4 再忽视~ 再到 1~
然而结果不是,希望有大佬能告知 [\dog]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值