2011-08-04 15 views
21

Un elemento es una lista delimitada por comas de una o más cadenas de números o caracteres, p.Java regex: grupos de captura de repetición

"12" 
"abc" 
"12,abc,3" 

Estoy tratando de coincidir con una lista entre corchetes de cero o más objetos en Java, por ejemplo,

"" 
"(12)" 
"(abc,12)" 
"(abc,12),(30,asdf)" 
"(qqq,pp),(abc,12),(30,asdf,2)," 

que debe devolver los siguientes grupos de juego, respectivamente, para el último ejemplo

qqq,pp 
abc,12 
30,asdf,2 

Yo he llegado con el patrón siguiente (incorrecta)

\((.+?)\)(?:,\((.+?)\))* 

que coincide con solamente el siguiente para el último ejemplo

qqq,pp 
30,asdf,2 

¿Sugerencias? Gracias

+2

¿Podría simplemente dividir la cadena en "), (" y eliminar los corchetes restantes para lograr el resultado? – Jens

+0

Definitivamente quiero ['Matcher.find()'] (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#find()). – Qix

Respuesta

33

Correcto. No puede tener una cantidad "variable" de grupos de captura en una expresión regular de Java. Su patrón tiene dos grupos:

\((.+?)\)(?:,\((.+?)\))* 
    |___|  |___| 
group 1  group 2 

Cada grupo contendrá el contenido de el último partido para ese grupo. Es decir, abc,12 quedará anulado por 30,asdf,2.

pregunta relacionada:

La solución es utilizar una expresión (algo así como \((.+?)\)) y utilizar matcher.find para iterar sobre los partidos.

+0

Argh ok gracias, no lo sabía, ahora tengo que encontrar una alternativa –

+0

Sí. Es molesto seguro. .net tiene la función (como se ve en la pregunta/respuesta a la que me he vinculado) – aioobe

+5

@David, en caso de que se haya perdido, ya le dio una buena alternativa :) – Svish

2

Puede usar expresiones regulares como ([^,]+) en bucle o solo str.split(",") para obtener todos los elementos a la vez. Esta versión: str.split("\\s*,\\s*") incluso permite espacios.

0

Ésta puede ser la solución:

package com.drl.fw.sch; 

import java.util.regex.Pattern; 

public class AngularJSMatcher extends SimpleStringMatcher { 

Matcher delegate; 


public AngularJSMatcher(String lookFor){ 
    super(lookFor); 
    // ng-repeat 
    int ind = lookFor.indexOf('-'); 
    if(ind >= 0){ 
     StringBuilder sb = new StringBuilder(); 
     boolean first = true; 
     for (String s : lookFor.split("-")){ 
      if(first){ 
       sb.append(s); 
       first = false; 
      }else{ 
       if(s.length() >1){ 
        sb.append(s.substring(0,1).toUpperCase()); 
        sb.append(s.substring(1)); 

       }else{ 
        sb.append(s.toUpperCase()); 
       } 
      } 
     } 
     delegate = new SimpleStringMatcher(sb.toString()); 
    }else { 
     String words[] = lookFor.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])"); 
     if(words.length > 1){ 
      StringBuilder sb = new StringBuilder(); 
      for (int i=0;i < words.length;i++) { 
       sb.append(words[i].toLowerCase()); 
       if(i < words.length-1) sb.append("-"); 
      } 
      delegate = new SimpleStringMatcher(sb.toString()); 
     } 

    } 

} 

@Override 
public boolean match(String in) { 
    if(super.match(in)) return true; 
    if(delegate != null && delegate.match(in)) return true; 

    return false; 
} 

public static void main(String[] args){ 
    String lookfor="ngRepeatStart"; 

    Matcher matcher = new AngularJSMatcher(lookfor); 

    System.out.println(matcher.match("<header ng-repeat-start=\"item in items\">")); 
    System.out.println(matcher.match("var ngRepeatStart=\"item in items\">")); 

} 

}

1

(^ | \ s +) (\ S *) (($ | \ s +) \ 2) + con la opción caso ignorar/i

Ella izquierda izquierda izquierda ahora

ejemplo aquí - https://regex101.com/r/FEmXui/2

Match 1 
Full match 3-23 ` left LEft leFT LEFT` 
Group 1. 3-4 ` ` 
Group 2. 4-8 `left` 
Group 3. 18-23 ` LEFT` 
Group 4. 18-19 ` ` 
Cuestiones relacionadas