Puede acceder a grupos de captura como este:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
Y si hay varias coincidencias, puede iterar sobre ellas:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
Editar: 2019-09-10
Como puede ver, la forma de iterar sobre múltiples coincidencias no era muy intuitiva. Esto condujo a la propuesta del String.prototype.matchAll
método. Se espera que este nuevo método se envíe en la especificación ECMAScript 2020 . Nos da una API limpia y resuelve múltiples problemas. Se ha comenzado a aterrizar en los principales navegadores y motores JS como Chrome 73+ / Node 12+ y Firefox 67+.
El método devuelve un iterador y se usa de la siguiente manera:
const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
for (const match of matches) {
console.log(match);
console.log(match.index)
}
Como devuelve un iterador, podemos decir que es vago, esto es útil cuando se manejan números particularmente grandes de grupos de captura, o cadenas muy grandes. Pero si lo necesita, el resultado se puede transformar fácilmente en una matriz utilizando la sintaxis de propagación o el Array.from
método:
function getFirstGroup(regexp, str) {
const array = [...str.matchAll(regexp)];
return array.map(m => m[1]);
}
// or:
function getFirstGroup(regexp, str) {
return Array.from(str.matchAll(regexp), m => m[1]);
}
Mientras tanto, aunque esta propuesta recibe un soporte más amplio, puede usar el paquete oficial de shim .
Además, el funcionamiento interno del método es simple. Una implementación equivalente usando una función generadora sería la siguiente:
function* matchAll(str, regexp) {
const flags = regexp.global ? regexp.flags : regexp.flags + "g";
const re = new RegExp(regexp, flags);
let match;
while (match = re.exec(str)) {
yield match;
}
}
Se crea una copia de la expresión regular original; Esto es para evitar efectos secundarios debido a la mutación de la lastIndex
propiedad al pasar por las coincidencias múltiples.
Además, debemos asegurarnos de que la expresión regular tenga la bandera global para evitar un bucle infinito.
También me alegra ver que incluso esta pregunta de StackOverflow fue mencionada en los debates de la propuesta .
var match = myString.match(myRegexp); // alert(match[1])
:?string = string.substring(match.index + match[0].length)
He aquí un método que se puede utilizar para obtener el n º captura de grupo para cada partido:
fuente
El
\b
no es exactamente lo mismo. (Funciona--format_foo/
, pero no funcionaformat_a_b
) Pero quería mostrar una alternativa a su expresión, que está bien. Por supuesto, lamatch
llamada es lo importante.fuente
format_a_b
" como un pensamiento posterior hace 6 años, y no recuerdo lo que quise decir allí ... :-) Supongo que significa "no funciona para capturara
solo", es decir. La primera parte alfabética despuésformat_
.Con respecto a los ejemplos de paréntesis de coincidencias múltiples anteriores, estaba buscando una respuesta aquí después de no obtener lo que quería de:
Después de mirar las llamadas de función ligeramente complicadas con while y .push () arriba, me di cuenta de que el problema se puede resolver de manera muy elegante con mystring.replace () en su lugar (el reemplazo NO es el punto, y ni siquiera se hace , la opción de llamada a la función recursiva incorporada LIMPIO para el segundo parámetro es!):
Después de esto, no creo que vuelva a usar .match () para casi nada nunca más.
fuente
Por último, pero no menos importante, encontré una línea de código que funcionó bien para mí (JS ES6):
Esto devolverá:
fuente
replace
enfoque completo de Alexz porque este es menos anticipado y más elegante para obtener múltiples resultados. Buen trabajo en esto, Sebastien H.Terminología utilizada en esta respuesta:
someString.match(regexPattern)
./format_(.*?)/g
dónde(.*?)
sería un grupo coincidente). Estos residen dentro de patrones coincidentes .Descripción
Para obtener acceso a los grupos coincidentes , en cada uno de los patrones coincidentes , necesita una función o algo similar para iterar sobre la coincidencia . Hay varias formas de hacerlo, como muestran muchas de las otras respuestas. La mayoría de las otras respuestas usan un ciclo while para iterar sobre todos los patrones coincidentes , pero creo que todos conocemos los peligros potenciales con ese enfoque. Es necesario hacer coincidir un
new RegExp()
patrón en lugar de solo el patrón en sí mismo, que solo se mencionó en un comentario. Esto se debe a que el.exec()
método se comporta de manera similar a una función generadora : se detiene cada vez que hay una coincidencia , pero.lastIndex
continúa desde allí en la próxima.exec()
llamada.Ejemplos de código
A continuación se muestra un ejemplo de una función
searchString
que devuelve unoArray
de todos los patrones coincidentes , donde cada unomatch
es unArray
con todos los grupos coincidentes que contienen . En lugar de usar un bucle while, he proporcionado ejemplos usando tanto laArray.prototype.map()
función como una forma másfor
eficiente : usando un bucle simple .Versiones concisas (menos código, más azúcar sintáctico)
Estos son menos
forEach
efectivos ya que básicamente implementan un bucle en lugar delfor
bucle más rápido.Versiones de rendimiento (más código, menos azúcar sintáctico)
Todavía tengo que comparar estas alternativas con las mencionadas anteriormente en las otras respuestas, pero dudo que este enfoque sea menos eficaz y menos a prueba de fallas que los otros.
fuente
String#matchAll
(vea el borrador de la Etapa 3 / propuesta del 7 de diciembre de 2018 ), simplifica el acceso a todos los grupos en el objeto de coincidencia (tenga en cuenta que el Grupo 0 es la coincidencia completa, mientras que otros grupos corresponden a los grupos de captura en el patrón):Este método produce una salida similar a
Regex.Matches
en C #,re.finditer
en Python,preg_match_all
en PHP.Vea una demostración de JS (probada en Google Chrome 73.0.3683.67 (versión oficial), beta (64 bits)):
Los
console.log([...matches])
showsTambién puede obtener un valor de coincidencia o valores de grupo específicos utilizando
NOTA : Consulte los detalles de compatibilidad del navegador .
fuente
Su sintaxis probablemente no sea la mejor para mantener. FF / Gecko define RegExp como una extensión de Function.
(FF2 fue tan lejos como
typeof(/pattern/) == 'function'
)Parece que esto es específico para FF: IE, Opera y Chrome arrojan excepciones para ello.
En su lugar, utilice cualquiera de los métodos mencionados anteriormente por otros:
RegExp#exec
oString#match
.Ofrecen los mismos resultados:
fuente
¡No hay necesidad de invocar el
exec
método! Puede usar el método de "coincidencia" directamente en la cadena. Simplemente no olvides los paréntesis.La posición 0 tiene una cadena con todos los resultados. La posición 1 tiene la primera coincidencia representada entre paréntesis, y la posición 2 tiene la segunda coincidencia aislada entre paréntesis. Los paréntesis anidados son complicados, ¡así que ten cuidado!
fuente
Un trazador de líneas que es práctico solo si tiene un par de paréntesis:
fuente
while (match = myRegex.exec(myStr)) matches.push(match[1])
Usando su código:
Editar: Safari 3, si es importante.
fuente
Con es2018 ahora puede
String.match()
con grupos con nombre, hace que su expresión regular sea más explícita de lo que estaba tratando de hacer.y obtendrás algo como
fuente
fuente
Su código funciona para mí (FF3 en Mac) incluso si estoy de acuerdo con PhiLo en que la expresión regular probablemente debería ser:
(Pero, por supuesto, no estoy seguro porque no conozco el contexto de la expresión regular).
fuente
fuente
Realmente no necesita un ciclo explícito para analizar múltiples coincidencias: pase una función de reemplazo como segundo argumento como se describe en
String.prototype.replace(regex, func)
:El
m0
argumento representa la subcadena coincidente completa{0}
,{1}
, etc.m1
representa el primer grupo de coincidencia, es decir, la parte encerrada entre paréntesis en la expresión regular que es0
para el primer partido. Yposition
es el índice inicial dentro de la cadena donde se encontró el grupo coincidente, no utilizado en este caso.fuente
En el código \ 1 representado coincide con el primer grupo ([az])
fuente
Solución de una línea:
Entonces puede usar de esta manera (debe usar / g):
resultado:
fuente
Obtener todas las ocurrencias grupales
fuente
Si eres como yo y deseo que regex devuelva un Objeto como este:
luego corta la función desde abajo
fuente
SOLO UTILICE RegExp. $ 1 ... $ n grupo, por ejemplo:
1.Para igualar el 1er grupo RegExp. $ 1
si usa 3 grupos en regex likey (tenga en cuenta el uso después de string.match (regex))
RegExp. $ 1 RegExp. $ 2 RegExp. $ 3
fuente