
gatlín
Estoy tratando de analizar el siguiente tipo de cadena:
[key:"val" key2:"val2"]
donde hay claves arbitrarias: pares “val” dentro. Quiero tomar el nombre de la clave y el valor. Para aquellos curiosos, estoy tratando de analizar el formato de la base de datos de Task Warrior.
Aquí está mi cadena de prueba:
[description:"aoeu" uuid:"123sth"]
lo que pretende resaltar que cualquier cosa puede estar en una clave o valor aparte del espacio, sin espacios alrededor de los dos puntos, y los valores siempre están entre comillas dobles.
En el nodo, esta es mi salida:
[deuteronomy][gatlin][~]$ node
> var re = /^\[(?:(.+?):"(.+?)"\s*)+\]$/g
> re.exec('[description:"aoeu" uuid:"123sth"]');
[ '[description:"aoeu" uuid:"123sth"]',
'uuid',
'123sth',
index: 0,
input: '[description:"aoeu" uuid:"123sth"]' ]
Pero description:"aoeu"
también coincide con este patrón. ¿Cómo puedo recuperar todos los partidos?

mar de césped
Continuar llamando re.exec(s)
en un bucle para obtener todas las coincidencias:
var re = /\s*([^[:]+):\"([^"]+)"/g;
var s="[description:"aoeu" uuid:"123sth"]";
var m;
do {
m = re.exec(s);
if (m) {
console.log(m[1], m[2]);
}
} while (m);
Pruébelo con este JSFiddle: https://jsfiddle.net/7yS2V/

anís
str.match(pattern)
si pattern
tiene la bandera mundial g
devolverá todas las coincidencias como una matriz.
Por ejemplo:
const str="All of us except @Emran, @Raju and @Noman were there";
console.log(
str.match(/@\w*/g)
);
// Will log ["@Emran", "@Raju", "@Noman"]

Cristóbal
Para recorrer todas las coincidencias, puede usar el replace
función:
var re = /\s*([^[:]+):\"([^"]+)"/g;
var s="[description:"aoeu" uuid:"123sth"]";
s.replace(re, function(match, g1, g2) { console.log(g1, g2); });

lovasoa
esta es una solucion
var s="[description:"aoeu" uuid:"123sth"]";
var re = /\s*([^[:]+):\"([^"]+)"/g;
var m;
while (m = re.exec(s)) {
console.log(m[1], m[2]);
}
Esto se basa en la respuesta de Lawnsea, pero más corta.
Tenga en cuenta que la bandera ‘g’ debe establecerse para mover el puntero interno hacia adelante a través de las invocaciones.

eaorak
str.match(/regex/g)
devuelve todas las coincidencias como una matriz.
Si, por alguna razón misteriosa, necesita la información adicional que viene con exec
como alternativa a las respuestas anteriores, podría hacerlo con una función recursiva en lugar de un bucle de la siguiente manera (que también se ve mejor :).
function findMatches(regex, str, matches = []) {
const res = regex.exec(str)
res && matches.push(res) && findMatches(regex, str, matches)
return matches
}
// Usage
const matches = findMatches(/regex/g, str)
como se indicó en los comentarios anteriores, es importante tener g
al final de la definición de expresiones regulares para mover el puntero hacia adelante en cada ejecución.
Finalmente estamos comenzando a ver una función integrada matchAll
función, ver aquí para la descripción y la tabla de compatibilidad. Parece que a partir de mayo de 2020, se admiten Chrome, Edge, Firefox y Node.js (12+), pero no IE, Safari y Opera. parece que fue redactado en diciembre de 2018 así que dale algo de tiempo para que llegue a todos los navegadores, pero confío en que llegará allí.
el incorporado matchAll
La función es agradable porque devuelve un iterable. ¡También regresa capturando grupos para cada partido! Entonces puedes hacer cosas como
// get the letters before and after "o"
let matches = "stackoverflow".matchAll(/(\w)o(\w)/g);
for (match of matches) {
console.log("letter before:" + match[1]);
console.log("letter after:" + match[2]);
}
arrayOfAllMatches = [...matches]; // you can also turn the iterable into an array
También parece que cada objeto de coincidencia usa el mismo formato que match()
. Entonces, cada objeto es una matriz de los grupos de coincidencia y captura, junto con tres propiedades adicionales index
, input
y groups
. Así que parece:
[<match>, <group1>, <group2>, ..., index: <match offset>, input: <original string>, groups: <named capture groups>]
Para más información sobre matchAll
también hay una Página de desarrolladores de Google. también hay rellenos de polietileno/calzas disponible.
Si tienes ES9
(Es decir, si su sistema: Chrome, Node.js, Firefox, etc. es compatible con Ecmascript 2019 o posterior)
Usa el nuevo yourString.matchAll( /your-regex/ )
.
Si no tienes ES9
Si tiene un sistema antiguo, aquí hay una función para copiar y pegar fácilmente
function findAll(regexPattern, sourceString) {
let output = []
let match
// make sure the pattern has the global flag
let regexPatternWithGlobal = RegExp(regexPattern,[...new Set("g"+regexPattern.flags)].join(""))
while (match = regexPatternWithGlobal.exec(sourceString)) {
// get rid of the string copy
delete match.input
// store the match data
output.push(match)
}
return output
}
ejemplo de uso:
console.log( findAll(/blah/g,'blah1 blah2') )
salidas:
[ [ 'blah', index: 0 ], [ 'blah', index: 6 ] ]
Puede ser que mi expresión regular sea incorrecta y/o que simplemente esté usando incorrectamente las funciones de expresión regular en JavaScript. Esto parece funcionar: > var s = “Quince es 15 y ocho es 8”; > var re = /\d+/g; > var m = s.match(re); metro = [ ’15’, ‘8’ ]
– Gatlin
12 de junio de 2011 a las 18:08
Javascript ahora tiene una función .match(): desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Usado así:
"some string".match(/regex/g)
– Stefnotch
5 de marzo de 2016 a las 9:37