regulares regular probar expresiones expresion espacio ejemplos crear blanco alfanumerico javascript regex capturing-group

probar - Obtener índice de cada captura en una expresión regular de JavaScript



expresiones regulares java (6)

Basándome en la sintaxis de expresión regular ecma , he escrito un analizador respectivo y una extensión de la clase RegExp que resuelve además de este problema (método exec indexado completo), así como otras limitaciones de la implementación de RegExp de JavaScript, por ejemplo: búsqueda y reemplazo basados ​​en grupos. Puede probar y descargar la implementación aquí (también está disponible como módulo NPM).

La implementación funciona de la siguiente manera (pequeño ejemplo):

//Retrieve content and position of: opening-, closing tags and body content for: non-nested html-tags. var pattern = ''(<([^ >]+)[^>]*>)([^<]*)(</////2>)''; var str = ''<html><code class="html plain">first</code><div class="content">second</div></html>''; var regex = new Regex(pattern, ''g''); var result = regex.exec(str); console.log(5 === result.length); console.log(''<code class="html plain">first</code>''=== result[0]); console.log(''<code class="html plain">''=== result[1]); console.log(''first''=== result[3]); console.log(''</code>''=== result[4]); console.log(5=== result.index.length); console.log(6=== result.index[0]); console.log(6=== result.index[1]); console.log(31=== result.index[3]); console.log(36=== result.index[4]);

Intenté también la implementación de @velop pero la implementación parece estar defectuosa, por ejemplo, no maneja correctamente las referencias inversas, por ejemplo, "/ a (?:) bc (def ( / 1 ghi) xyz) / g" - al agregar paréntesis delante la referencia inversa / 1 debe incrementarse en consecuencia (lo que no es el caso en su implementación).

Quiero hacer coincidir una expresión regular como /(a).(b)(c.)d/ con "aabccde" , y obtener la siguiente información:

"a" at index = 0 "b" at index = 2 "cc" at index = 3

¿Cómo puedo hacer esto? String.match devuelve la lista de coincidencias y el índice del inicio de la coincidencia completa, no el índice de cada captura.

Edición: un caso de prueba que no funcionaría con indexOf simple

regex: /(a).(.)/ string: "aaa" expected result: "a" at 0, "a" at 2

Nota: la pregunta es similar a Javascript Regex: ¿Cómo encontrar el índice de cada subexpresión? , pero no puedo modificar la expresión regular para hacer de cada subexpresión un grupo de captura.


Con RegExp.prototype.exec () y buscando los índices adecuados del resultado:

let regex1 = /([a-z]+):([0-9]+)/g; let str1 = ''hello:123''; let array1; let resultArray = [] while ((array1 = regex1.exec(str1)) !== null) { const quantityFound = (Object.keys(array1).length - 3); // 3 default keys for (var i = 1; i<quantityFound; i++) { // start in 1 to avoid the complete found result ''hello:123'' const found = array1[i]; arraySingleResult = [found, str1.indexOf(found)]; resultArray.push(arraySingleResult); } } console.log(''result:'', JSON.stringify(resultArray));


Creé un pequeño analizador de expresiones regulares que también puede analizar grupos anidados como un encanto. Es pequeño pero enorme. No realmente. Como las manos de donalds. Estaría muy feliz si alguien pudiera probarlo, por lo que será probado en batalla. Se puede encontrar en: https://github.com/valorize/MultiRegExp2

Uso:

let regex = /a(?: )bc(def(ghi)xyz)/g; let regex2 = new MultiRegExp2(regex); let matches = regex2.execForAllGroups(''ababa bcdefghixyzXXXX'')); Will output: [ { match: ''defghixyz'', start: 8, end: 17 }, { match: ''ghi'', start: 11, end: 14 } ]


Entonces, tienes un texto y una expresión regular:

txt = "aabccde"; re = /(a).(b)(c.)d/;

El primer paso es obtener la lista de todas las subcadenas que coinciden con la expresión regular:

subs = re.exec(txt);

Luego, puede hacer una búsqueda simple en el texto para cada subcadena. Deberá mantener en una variable la posición de la última subcadena. He nombrado este cursor variable.

var cursor = subs.index; for (var i = 1; i < subs.length; i++){ sub = subs[i]; index = txt.indexOf(sub, cursor); cursor = index + sub.length; console.log(sub + '' at index '' + index); }

EDITAR: Gracias a @nhahtdh, mejoré el mecanismo e hice una función completa:

String.prototype.matchIndex = function(re){ var res = []; var subs = this.match(re); for (var cursor = subs.index, l = subs.length, i = 1; i < l; i++){ var index = cursor; if (i+1 !== l && subs[i] !== subs[i+1]) { nextIndex = this.indexOf(subs[i+1], cursor); while (true) { currentIndex = this.indexOf(subs[i], index); if (currentIndex !== -1 && currentIndex <= nextIndex) index = currentIndex + 1; else break; } index--; } else { index = this.indexOf(subs[i], cursor); } cursor = index + subs[i].length; res.push([subs[i], index]); } return res; } console.log("aabccde".matchIndex(/(a).(b)(c.)d/)); // [ [ ''a'', 1 ], [ ''b'', 2 ], [ ''cc'', 3 ] ] console.log("aaa".matchIndex(/(a).(.)/)); // [ [ ''a'', 0 ], [ ''a'', 1 ] ] <-- problem here console.log("bababaaaaa".matchIndex(/(ba)+.(a*)/)); // [ [ ''ba'', 4 ], [ ''aaa'', 6 ] ]


Escribí MultiRegExp para esto hace un tiempo. Mientras no tenga grupos de captura anidados, debería hacer el truco. Funciona insertando grupos de captura entre los de su RegExp y utilizando todos los grupos intermedios para calcular las posiciones de grupo solicitadas.

var exp = new MultiRegExp(/(a).(b)(c.)d/); exp.exec("aabccde");

debería regresar

{0: {index:0, text:''a''}, 1: {index:2, text:''b''}, 2: {index:3, text:''cc''}}

Versión en vivo


No estoy exactamente seguro de cuáles son sus requisitos para su búsqueda, pero a continuación le Regex.exec() cómo puede obtener el resultado deseado en su primer ejemplo utilizando Regex.exec() y un bucle while.

JavaScript

var myRe = /^a|b|c./g; var str = "aabccde"; var myArray; while ((myArray = myRe.exec(str)) !== null) { var msg = ''"'' + myArray[0] + ''" ''; msg += "at index = " + (myRe.lastIndex - myArray[0].length); console.log(msg); }

Salida

"a" at index = 0 "b" at index = 2 "cc" at index = 3

Usando la propiedad lastIndex , puede restar la longitud de la cadena coincidente actualmente para obtener el índice de inicio.