正则表达式*和+问题求解

告诉我们发生了什么:
r1为什么匹配不到s?而r5中的可以匹配到s

代码


let s='caxsaxx'
let r1=/s*/
console.log(s.match(r1))

let r5=/c*/
console.log(s.match(r5))

let r2=/s+/
console.log(s.match(r2))

let r3=/xs*/
console.log(s.match(r3))

let r4=/xs+/
console.log(s.match(r4))

结果

[ ‘’, index: 0, input: ‘caxsaxx’, groups: undefined ]
[ ‘c’, index: 0, input: ‘caxsaxx’, groups: undefined ]
[ ‘s’, index: 3, input: ‘caxsaxx’, groups: undefined ]
[ ‘xs’, index: 2, input: ‘caxsaxx’, groups: undefined ]
[ ‘xs’, index: 2, input: ‘caxsaxx’, groups: undefined ]

我刚刚运行了你的代码,并将c放到了第二位发现,r5也像r1一样,再加上*代表0次或者多次,可以推断因为第一个字符没有判断到就返回了0次

因为是可以匹配到0次的,当你只输入一个数字用匹配的时候,除非那个数字在第一个位置上,否则会返回0,我测试了很多次,可能是因为*懒吧,只匹配了第一个位置上的,然后就结束了,所以加上g后就都可以了,后面我又测试到如果输入有比如as,他就会去匹配全局,所以我也挺迷糊的,希望还有更详细的解释吧

在你所列举的一些例子中,应该除了 s.match(r1) 的结果不太好理解之外,其余的应该还是比较好理解的,那么我就尝试以 'caxsaxx'.match(/s*/) 为例来解释一下。

首先根据我们先来看一下 match 方法的返回值是什么:

  • 如果使用g标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。
  • 如果未使用g标志,则仅返回第一个完整匹配及其相关的捕获组( Array )。 在这种情况下,返回的项目将具有如下所述的其他属性。
    来源:MDN String.prototype.match

也就是说如果我们使用 /s*/g 的形式来 match 结果,就会返回所有的匹配结果,如果使用 /s*/ 则只返回第一个结果。我们先使用 /s*/g 看下输出结果是什么:

const str = 'caxsaxx';
const regex = /s*/g;

console.log(str.match(regex));
//输出:  ['', '', '', 's', '', '', '', '']

这么来看也就不难理解为什么 /s*/ 的匹配结果是 '' 了,但为什么 /s*/g 的匹配结果是上面所示的呢?我来简单展示一下匹配过程:

// 第1次使用 c 匹配,得到结果 ''
// 第2次使用 a 匹配,得到结果 ''
// 第3次使用 x 匹配,得到结果 ''
// 第4次使用 s 匹配,得到结果 's'
// 第5次使用 a 匹配,得到结果 ''
// 第6次使用 x 匹配,得到结果 ''
// 第7次使用 x 匹配,得到结果 ''

假如我们使用 /xs*/g 来进行匹配,匹配过程是什么样的呢?

// 第1次使用 xs 匹配,得到结果 'xs'
// 第2次使用 x 匹配,得到结果 'x'
// 第3次使用 x 匹配,得到结果 'x'

为什么第一次匹配是 xs 而不是 x 呢?是因为 * 在匹配过程中会尽可能多地匹配符合规则的内容,它是“贪婪”的。在正则表达式中可以使用 ? 来使用非贪婪模式,你可以尝试一下 /xs*?/g 的匹配结果就是 ['x', 'x', 'x'],而不是之前的 ['xs', 'x', 'x'] :wink:

– 我是来自成都freeCodeCamp的牛牛,希望对你有帮助 –

2 个赞