981377660LMT / ts

ts学习
6 stars 1 forks source link

正则表达式g的状态 #561

Open 981377660LMT opened 3 months ago

981377660LMT commented 3 months ago

如果你发现使用正则表达式 PEOPLE_REGEXP.test(componentType || '') 的匹配结果在相同输入下每次都不同,那么很可能是因为你的正则表达式对象使用了全局标志(g)。在JavaScript中,正则表达式对象带有全局标志时会记住上次匹配的位置,下一次匹配会从上次匹配结束的位置开始。

例如,假设 PEOPLE_REGEXP 是这样定义的:

const PEOPLE_REGEXP = /people|multiplepeople/gi;

这里的 g 表示全局搜索,i 表示不区分大小写。当你多次对同一个字符串使用 test 方法时,由于正则表达式对象记住了上次匹配的位置,可能会导致看似相同的测试返回不同的结果。

看下面的例子:

const PEOPLE_REGEXP = /people|multiplepeople/gi;

console.log(PEOPLE_REGEXP.test('people')); // true
console.log(PEOPLE_REGEXP.test('people')); // false

第一次调用 test 方法时,从字符串开始位置匹配成功,返回 true。第二次调用时,由于正则表达式对象记住了上次匹配的位置(即字符串的末尾),从那里开始就无法再次匹配到相同的模式,因此返回 false

解决方法

  1. 不使用全局标志:如果你不需要全局搜索,去掉正则表达式的 g 标志。

    const PEOPLE_REGEXP = /people|multiplepeople/i; // 移除了g标志
  2. 每次匹配前重置 lastIndex:如果你需要使用全局标志,可以在每次匹配前手动重置 lastIndex 属性。

    PEOPLE_REGEXP.lastIndex = 0;
    console.log(PEOPLE_REGEXP.test('people')); // true
    PEOPLE_REGEXP.lastIndex = 0;
    console.log(PEOPLE_REGEXP.test('people')); // true
  3. 每次都创建一个新的正则表达式对象:这样可以确保每次匹配都是从头开始。

    console.log(/people|multiplepeople/gi.test('people')); // true
    console.log(/people|multiplepeople/gi.test('people')); // true

选择哪种方法取决于你的具体需求和场景。

981377660LMT commented 3 months ago

在JavaScript的正则表达式中,g标志表示“全局”搜索。使用g标志的目的是让正则表达式匹配字符串中的所有可能匹配项,而不是在找到第一个匹配项后就停止。这意味着,如果你使用g标志,可以在一个字符串中查找所有匹配正则表达式的子串。

g标志的特点:

使用g标志的例子:

不使用g标志:

const regex = /abc/;
const str = 'abc abc abc';
const matches = str.match(regex);
console.log(matches[0]); // "abc"
// 只匹配到了第一个"abc"

使用g标志:

const regex = /abc/g;
const str = 'abc abc abc';
const matches = str.match(regex);
console.log(matches); // ["abc", "abc", "abc"]
// 匹配到了所有的"abc"

注意事项:

总的来说,g标志提供了在整个字符串中进行全面搜索的能力,但在使用时需要注意其特有的行为和影响。