regex 有没有一种方法可以使用JavaScript获取正则表达式模式的所有匹配?[副本]

plupiseo  于 12个月前  发布在  Java
关注(0)|答案(3)|浏览(92)

此问题已在此处有答案

RegEx to extract all matches from string using RegExp.exec(19回答)
上个月关门了。
我正在编写一些代码,可以从一个文本块中提取所有链接。我有一个正则表达式模式,我只是想知道是否有一种方法可以得到所有匹配的正则表达式模式?
我尝试了一些代码,但每次都没有返回任何东西。
任何答案都很感激。

let string = "Hello world"
let m, newtext, re = /o/g
do {
  m = re.exec(string);
  if (m) {
    newtext = (m[1], m[2]);
  }
} while (m);

console.log(m,newtext)

这不是一个重复的职位没有解决我的问题。
我也用了这个代码,但我得到一个错误:“findAll不是函数或其返回值不可迭代”

function link() {
        const findAll = (value, expr) => {

            const iterator = value.matchAll(typeof expr === 'string' ? 
            new RegExp(expr, 'gd') : 
            new RegExp(expr.source, [...new Set((expr.flags + 'gd').split(''))].join('')));
            let _next;
            [_next, iterator.next] = [iterator.next, function(){
              const result = _next.call(iterator);
              if(!result.done){
                const {0: text, indices: [[startIndex, endIndex]]} = result.value;
                console.log(
                 'done:', false,
                 'value:', {text, startIndex, endIndex} 
                );
              }
              
              console.log (result);
            }];
            console.log(iterator);
          }
          
          console.log('matching with string:');
          for (const m of findAll(str, re)) {
            console.log(JSON.stringify(m));
          }
          
          console.log('matching with regex:');
          for (const m of findAll(str, re)) {
            console.log(JSON.stringify(m));
          }
    }
pn9klfpd

pn9klfpd1#

跳上马车,这里是一个修改版本的先生。Polywhirl的回应:
1.返回.matchAll的迭代器,这样我们就可以使用迭代器的所有优点,例如,我们可以中断循环,从而跳过其余部分并优化性能。

  1. Moncleratch迭代器的.next()以获得我们需要的格式的数据。
    1.将d标志添加到正则表达式中,以便我们可以自动获取开始和结束匹配索引
    1.通过添加gd标志来修复第二个参数(如果是regexp)
const findAll = (value, expr) => {

  const iterator = value.matchAll(typeof expr === 'string' ? 
  new RegExp(expr, 'gd') : 
  new RegExp(expr.source, [...new Set((expr.flags + 'gd').split(''))].join('')));
  let _next;
  [_next, iterator.next] = [iterator.next, function(){
    const result = _next.call(iterator);
    if(!result.done){
      const {0: text, indices: [[startIndex, endIndex]]} = result.value;
      return {
        done: false,
        value: {text, startIndex, endIndex} 
      }
    }
    
    return result;
  }];
  return iterator;
}

console.log('matching with string:');
for (const m of findAll('table football, foosball', 'foo[a-z]*')) {
  console.log(JSON.stringify(m));
}

console.log('matching with regex:');
for (const m of findAll('table football, foosball', /foo[a-z]*/g)) {
  console.log(JSON.stringify(m));
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
pzfprimi

pzfprimi2#

正如@Konrad所说。最好的方法之一是使用matchAll。范例:

const regexp = /foo[a-z]*/g;
const str = "table football, foosball";
const matches = str.matchAll(regexp);

for (const match of matches) {
  console.log(
    `Found ${match[0]} start=${match.index} end=${
      match.index + match[0].length
    }.`,
  );
}
// Found football start=6 end=14.
// Found foosball start=16 end=24.
1qczuiv0

1qczuiv03#

以下是Jivopis回应的修改版本。
我创建了一个名为findAll的函数,它接受一个字符串和一个模式(字符串或正则表达式),并返回一个对象列表。这些对象包含原始文本中每个匹配子字符串的textstartIndexendIndex

/**
 * An object representing match info.
 * @typedef {Object} MatchInfo
 * @property {string} text - The matched substring text
 * @property {number} startIndex - The subtring start index
 * @property {number} endIndex - The substring end index
 */

 /**
 * Returns all matching substrings, along with their start and end indices.
 *
 * @param {string} value - The text to search
 * @param {RegExp|string} expr - A pattern to search with
 * @returns {MatchInfo[]} - Matches
 */
const findAll = (value, expr) =>
  [...value.matchAll(typeof expr === 'string' ? new RegExp(expr, 'g') : expr)]
    .map(({ 0: s, index: i }) => ({ text: s, startIndex: i, endIndex: i + s.length }))

const matches = findAll('table football, foosball', 'foo[a-z]*');

for (let match of matches) {
  console.log(match);
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

输出

[{
  "text": "football",
  "startIndex": 6,
  "endIndex": 14
}, {
  "text": "foosball",
  "startIndex": 16,
  "endIndex": 24
}]

相关问题