Capturar y agrupar
El grupo de captura (pattern)
crea un grupo que tiene propiedad de captura .
Uno relacionado que a menudo puede ver (y usar) es (?:pattern)
, que crea un grupo sin capturar la propiedad, de ahí el nombre de grupo no capturador .
Por lo general, se utiliza un grupo cuando se necesita repetir una secuencia de patrones, por ejemplo (\.\w+)+
, o para especificar dónde debe tener efecto la alternancia, por ejemplo ^(0*1|1*0)$
( ^
, entonces 0*1
o 1*0
, luego $
) versus ^0*1|1*0$
( ^0*1
o 1*0$
).
Un grupo de captura, además de agrupar, también registrará el texto que coincide con el patrón dentro del grupo de captura (pattern)
. Usando su ejemplo (.*):
, .*
partidos ABC
y :
partidos :
, y dado que .*
está dentro de captura de grupo (.*)
, el texto ABC
se registra para el grupo de captura 1.
Número de grupo
El patrón completo se define como el grupo número 0.
Cualquier grupo de captura en el patrón comienza a indexar desde 1. Los índices se definen por el orden de los paréntesis de apertura de los grupos de captura . Como ejemplo, aquí están los 5 grupos de captura en el siguiente patrón:
(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
| | | | | | || | |
1-----1 | | 4------4 |5-------5 |
| 3---------------3 |
2-----------------------------------------2
Los números de grupo se utilizan en referencia \n
inversa en patrón y $n
en cadena de reemplazo.
En otros sabores de expresiones regulares (PCRE, Perl), también se pueden usar en llamadas a subrutinas .
Puede acceder al texto que coincide con cierto grupo con Matcher.group(int group)
. Los números de grupo se pueden identificar con la regla indicada anteriormente.
En algunos tipos de expresiones regulares (PCRE, Perl), hay una función de reinicio de rama que le permite usar el mismo número para capturar grupos en diferentes ramas de alternancia .
Nombre del grupo
Desde Java 7, puede definir un grupo de captura con nombre (?<name>pattern)
y puede acceder al contenido que coincide con Matcher.group(String name)
. La expresión regular es más larga, pero el código es más significativo, ya que indica lo que está intentando hacer coincidir o extraer con la expresión regular.
Los nombres de los grupos se utilizan como referencia \k<name>
inversa en el patrón y ${name}
en la cadena de reemplazo.
Los grupos de captura con nombre todavía están numerados con el mismo esquema de numeración, por lo que también se puede acceder a ellos a través de Matcher.group(int group)
.
Internamente, la implementación de Java simplemente se asigna desde el nombre al número de grupo. Por lo tanto, no puede utilizar el mismo nombre para 2 grupos de captura diferentes.
Para el resto de nosotros
Aquí hay un ejemplo simple y claro de cómo funciona esto.
Regex:
([a-zA-Z0-9]+)([\s]+)([a-zA-Z ]+)([\s]+)([0-9]+)
Cuerda:
"!* UserName10 John Smith 01123 *!"
Como puede ver, he creado CINCO grupos, cada uno entre paréntesis.
Incluí el! * Y *! a cada lado para que quede más claro. Tenga en cuenta que ninguno de esos caracteres está en la expresión regular y, por lo tanto, no aparecerá en los resultados. El grupo (0) simplemente le da la cadena completa coincidente (todos mis criterios de búsqueda en una sola línea). El grupo 1 se detiene justo antes del primer espacio porque el carácter de espacio no se incluyó en los criterios de búsqueda. Los grupos 2 y 4 son simplemente el espacio en blanco, que en este caso es literalmente un carácter de espacio, pero también podría ser una pestaña o un salto de línea, etc. El grupo 3 incluye el espacio porque lo puse en los criterios de búsqueda ... etc.
Espero que esto tenga sentido.
fuente
Los paréntesis
()
se utilizan para permitir la agrupación de frases de expresiones regulares.El
group(1)
contiene la cadena que está entre paréntesis,(.*)
así que.*
en este casoY
group(0)
contiene una cadena completa a juego.Si tuviera más grupos (leer
(...)
), se colocarían en grupos con los siguientes índices (2, 3, etc.).fuente