35 Stimmen

Wie findet man Indizes von Gruppen in JavaScript regulären Ausdrücken entsprechen?

Wenn ich einen regulären Ausdruck schreibe wie:

var m = /(s+).*?(l)[^l]*?(o+)/.exec("this is hello to you");
console.log(m);

Ich erhalte ein Match-Objekt mit folgendem Inhalt:

{
  0: "s is hello",
  1: "s",
  2: "l",
  3: "o",
  index: 3,
  input: "this is hello to you"
}

Ich kenne den Index des gesamten Spiels aus der index Eigenschaft, aber ich muss auch den Anfang und das Ende der zugeordneten Gruppen kennen. Mit einer einfachen Suche wird das nicht funktionieren. In diesem Beispiel wird das erste "l" anstelle des ersten in der Gruppe gefundenen gefunden.

Gibt es eine Möglichkeit, den Offset einer abgestimmten Gruppe zu ermitteln?

0voto

cancerbero Punkte 6226

Für globale Regex wollen Sie nur Fragmente abgleichen und iterieren, so dass die erste Lösung nicht funktionieren wird. Dies ist eine 30-minütige Lösung basierend auf indexOf und Summen, die für diesen Fall funktionieren:

https://codepen.io/cancerberoSgx/pen/qYwjjz?editors=0012#code-area

!function () {
  const regex = /\/\*\*\*@\s*([^@]+)\s*(@\*\*\*\/)/gim
  const exampleThatMatch = `
    /***@
    debug.print('hello editor, simpleNode kind is ' +
    arg.simpleNode.getKindName())
    @***/

    const a = 1 //user

    /***@
    debug.print(arg.simpleNode.getParent().getKindName())
    @***/
    `
  const text = exampleThatMatch 
  function exec(r, s) {
    function indexOfGroup(match, n) {
      var ix = match.index;
      for (var i = 1; i < n; i++)
        ix += match[i].length;
      return ix;
    }
    let result
    let lastMatchIndex = 0
    const matches = []
    while ((result = regex.exec(text))) {
      const match = []
      lastMatchIndex = text.indexOf(result[0], lastMatchIndex)
      let relIndex = 0 
      for (let i = 1; i < result.length; i++) {
        relIndex = text.indexOf(result[i], relIndex)
        match.push({ value: result[i], start: relIndex, end: relIndex + result[i].length })
      }
      matches.push(match)
    }
    return matches
  }
  const groupsWithIndex = exec(regex, text)
  console.log({RESULT: groupsWithIndex })
  // now test - let's remove everything else but matched groups 
  let frag = '' , sep = '\n#######\n'
  groupsWithIndex.forEach(match => match.forEach(group => {
    frag += text.substring(group.start, group.end) + sep
  }))
  console.log('The following are only the matched groups usign the result and text.substring just to verify it works OK:', '\n'+sep)
  console.log(frag)
}()

Und nur für den Fall, dass Sie es brauchen, hier ist das Typoskript:

https://codepen.io/cancerberoSgx/pen/yjrXxx?editors=0012

| Genießen Sie

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X