2012-03-01 15 views
9

Tengo problemas con mi expresión regular para capturar palabras consecutivas en mayúscula. Aquí es lo que yo quiero la expresión regular para capturar:Obtenga palabras en mayúscula consecutivas usando regex

"said Polly Pocket and the toys" -> Polly Pocket 

Aquí es la expresión regular que estoy utilizando:

re.findall('said ([A-Z][\w-]*(\s+[A-Z][\w-]*)+)', article) 

Devuelve el siguiente:

[('Polly Pocket', ' Pocket')] 

quiero que vuelva :

['Polly Pocket'] 
+0

Entonces, ¿qué si la entrada fue ' Tengo una cadena y es larga' ¿Debería dar '['Tener una cadena', 'Es larga']' o '['Tener una cadena y es larga'] ' –

+0

¿Por qué tiene la palabra" dicho "en su lista completa? ¿Realmente tiene la intención de encontrar palabras capitales consecutivas después de "dicho"? – jgritty

Respuesta

23

Utilice un preanálisis positivo:

([A-Z][a-z]+(?=\s[A-Z])(?:\s[A-Z][a-z]+)+) 

afirmar que la palabra actual, para ser aceptado, debe ser seguida por otra palabra con una letra mayúscula en ella. Analizado:

(    # begin capture 
    [A-Z]   # one uppercase letter \ First Word 
    [a-z]+   # 1+ lowercase letters/
    (?=\s[A-Z])  # must have a space and uppercase letter following it 
    (?:    # non-capturing group 
    \s    # space 
    [A-Z]   # uppercase letter \ Additional Word(s) 
    [a-z]+   # lowercase letter /
)+    # group can be repeated (more words) 
)    #end capture 
+0

Esto todavía da '['Polly Pocket', 'Pocket']' cuando lo ejecuto. –

+0

@Adam: tuvo que ver con el grupo interno también capturando. Ejecuta lo que tengo ahora, publica la adición del desglose. –

+0

Y un gran +1 para usted, señor. :) –

6

Es porque findall declaraciones de todos los grupos de captura en su expresión regular, y que tiene dos grupos de captura (uno que recibe todo el texto coincidente, y la interior de las palabras posteriores).

Usted puede simplemente hacer su segundo grupo de captura en un no-captura de uno mediante el uso de (?:regex) en lugar de (regex):

re.findall('([A-Z][\w-]*(?:\s+[A-Z][\w-]*)+)', article) 
+0

No creo que 'dicho' fue pensado como parte de la expresión regular. Es decir: 'le gusta Polly Pocket 'debería devolver los mismos partidos. –

+0

oh disculpas, copié ciegamente de OP. –

4
$mystring = "the United States of America has many big cities like New York and Los Angeles, and others like Atlanta"; 

@phrases = $mystring =~ /[A-Z][\w'-]\*(?:\s+[A-Z][\w'-]\*)\*/g; 

print "\n" . join(", ", @phrases) . "\n\n# phrases = " . scalar(@phrases) . "\n\n"; 

SALIDA:

$ ./try_me.pl 

United States, America, New York, Los Angeles, Atlanta 

\# phrases = 5 
Cuestiones relacionadas