贪婪和懒惰匹配
我们看个例子:
const text = '<div>hello</div><div>kkk</div>'
const reg = /<div>.*<\/div>/g
console.log('匹配内容', text.match(reg))
// 输出:匹配内容 ["<div>hello</div><div>kkk</div>"]
我们的本意是匹配的结果是这样的[<div>hello</div>, <div>kkk</div>],即找到每一对div标签。
结果输出匹配的却是,从开头的div标签到结尾的div的所有内容。为什么会出现这种情况呢?
是因为*, +, {n, }是贪婪型元字符,他们匹配规则是多多益善,而不是适可而止。这句话,是怎么理解的呢。
const reg = /<div>.*<\/div>/g
我们看看上述的正则,其意思是匹配以<div>开始 + 任意字符 + </div>结尾,且不区分大小写的。
贪婪匹配的意思:吃着碗里,看着锅里。利益最大化的代表。
懒惰匹配的意思:就是跟贪婪相反的,吃着碗里,绝不看着锅里。目光短浅的代表。
那如果我们想要懒惰匹配的话,我们应该怎么写呢?只需要在这些*, +, {n, }贪婪型元字符,添加?即可。
即*?, +?, {n,}?
还是上述的例子,我们想要达到我们初始想要的那种需求,即找出每一对div标签内容,那就需要把正则调整成
下面这种形式。
const text = '<div>hello</div><div>kkk</div>'
const reg = /<div>.*?<\/div>/g
console.log('匹配内容', text.match(reg))
// 匹配内容 (2) ["<div>hello</div>", "<div>kkk</div>"]
位置匹配
- 字符串的边界:
^代表字符串的开始,$代表字符串结尾。就是代表你需要匹配的字符串, 必须以^后面的字符开头,$前的字符结尾,才是符合我们查找的字符串,不然则不是。
详细的使用方法,请看下面示例
const text = 'ben';
// 下面三种写法,都能匹配到text
const reg1 = /^ben$/ // 这个代表查找,字母b开头,且中间为字母e, 结尾是必须是字母n的字符串
const reg2 = /^be./ // 这个代表查找,字母b开发,中间为字母e, 结尾为任意字符的字符串
const reg3 = /.*n$/ // 这个代表查找,开头为0个或者多个任意字符且结尾为n的字符串
console.log(text.match(reg1))
console.log(text.match(reg2))
console.log(text.match(reg3))
// 输出的结果为
// [ 'ben', index: 0, input: 'ben', groups: undefined ]
我们稍微改写下上面的那个例子
const text = 'ben ben ben';
const reg1 = /^ben$/g // 由于text文本存在多个ben和空格,导致匹配为null
const reg2 = /^be./g
// 刚好匹配到第一个ben,因为text就是以字母b开头的,满足正则条件的就是第一个ben字符串
const reg3 = /.*n$/g // 匹配到整个字符串ben ben ben, 因为text的末尾刚好是n
console.log(text1.match(reg1))
console.log(text1.match(reg2))
console.log(text1.match(reg3))
// 输出的结果为
null
[ 'ben' ]
[ 'ben ben ben' ]
-
\b代表单词边界,匹配一个单词的开始和结尾的位置,即匹配的单词字符,前后不能有\w的字符跟着。\w(小写)单词构成单词字符 (等价于[A-Za-z0-9_])\W(大写)不能构成单词的字符(等价于/[^A-Za-z0-9_]/)- 只是匹配一个位置,并不匹配任何字符
/\bcap\b/匹配的是cap这三个字符,并不是5个字符
const text = 'ben is ben is ben'
const reg = /\bben\b/ // 代表的意思:ben这个词前后,都没有字符跟着
const reg1 = /\bben\b/g
console.log(text.match(reg))
// 我们可以看出,\b不匹配字符的,仅仅只是一个占位而已
// 输出: ['ben', index: 0, input: 'ben is ben is ben', groups: undefined]
console.log(text.match(reg1))
// 输出: ['ben', 'ben', 'ben']
const reg2 = /e\b/
console.log(text.match(reg2))
// 输出:null
// 因为字母e,后面还有字母n, 那就不代码单词的边界
const text3 = 'ben is b_%en% is ben'
const reg3 = /\bb_%en\b/g
// 这个正则的意思:b_%en的字符前后都没有符合\w的字符跟着。
console.log(text3.match(reg3))
// 输出:['b_%en']
-
\B将匹配一个前后都不能构成单词的位置,即跟\b相反的例如:
xxx - xxx \B-\B将匹配中间的连字符(即中横线),因为刚好xxx的后面有空格,符合\B+-+ xxx前面的空格\B。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情