2015-11-15 20 views
5

Sto tentando di utilizzare Python RegEx re.sub per rimuovere i due punti prima della virgola antepenultimate [aeiou] di una parola se la vocale antepenultimate (dalla fine) è preceduta da un'altra vocale.Python RegEx utilizzando re.sub con più pattern

Quindi il colon deve essere compreso tra il 3 ° e il 4 ° conteggio delle vocali dalla fine della parola.

Quindi il 1o esempio fornito si suddividerebbe in questo modo w4:32ny1h.

Di seguito è riportata la dichiarazione RegEx che sto tentando di utilizzare ma non riesco a farla funzionare.

word = re.sub(ur"([aeiou]):([aeiou])(([^aeiou])*([aeiou])*([aeiou])([^aeiou])*([aeiou]))$", ur'\1\2\3\4', word) 
+0

Quindi, fondamentalmente la ricerca di due vocali collegati da due punti? – Ionut

+0

il colon deve essere compreso tra il 3 ° e il 4 ° conteggio delle vocali dalla fine della parola. quindi il 1 ° esempio dato si interromperà in questo modo w4: 32ny1h. – user2743

+0

Bello specificare :) pensato dopo aver decodificato il tuo pattern :) – Ionut

risposta

0

Dovrebbe funzionare con questo:

word = re.sub(ur"(?<=[aeiou]):(?=[aeiou]([^aeiou]*[aeiou]){2}[^aeiou]*$)", ur'', word) 

veda ad esempio qui: https://regex101.com/r/kA8xH3/2

avviso che ho catturare solo il colon e sostituirlo con una stringa vuota piuttosto che gruppi di cattura e concatenarle .

Tt controlla la combinazione di due punti, quindi esegue una verifica per verificare che ci siano 2 vocali aggiuntive (e forse consonanti). Permette allso consonanti aggiuntivi alla fine, ma fa in modo che non ci sono più vocale attraverso il $

+1

[^ aeiou] * $ la stella dice che può essere 0 o più, quindi può terminare con 0 consonanti che significa vocale – Alexander

+0

questo fallirà se c'è uno spazio o un altro personaggio :) Solo cercando di ottenere anche lol – Ionut

+0

@lonut Dove? Io uso '[^ aeiou]' quindi il secondo dovrebbe includere spazio e caratteri speciali, non dovrebbe? E se il mio lo fa, lo faresti anche tu, giusto? ;) – Alexander

1

Non basta avere troppi parentesi (e altre cose in più) ?:

word = re.sub(ur"([aeiou]):(([aeiou][^aeiou]*){3})$", ur'\1\2', word) 
+0

Questo non farà in modo che il primo carattere dopo il colon sia una vocale, vedi la mia risposta. – Ionut

+0

'[^ aeiou]' corrisponde a spazi, line feed, altri due punti e segni di punteggiatura. – dawg

0

Questa volontà farlo:

word = re.sub(ur"([aeiou]):([aeiou])([^\Waeiou]*[aeiou][^\Waeiou]*[aeiou][^\Waeiou]*)$", ur'\1\2\3', word) 

http://www.phpliveregex.com/p/dCa

+0

che non funzionerà. Nella tua espressione ci devono essere 2 vocali dopo i due punti, il che significa che qualcosa come il 2 ° e il 3 ° esempio non verranno catturati – Alexander

+0

sì, l'ho visto. Ma tu hai '([aeiou]): ([aeiou]) (([aeiou]' che dice che ci devono essere 3 vocali di fila, con il 1 ° e il 2 ° con due punti tra loro – Alexander

+0

sì e che cos'è tra ': ([aeiou])' e '(([aeiou] [^ aeiou] *) {2})'? non è consentita un'altra consonante, quindi qualcosa come 'dsa: adaa' non sarebbe consentito – Alexander

1

Non sono sicuro se si vuole ignorare completamente consonanti; questa regex lo farà. Altrimenti simile a quello di Jeff.

import re 

tests = [ 
    'we:aanyoh', 
    'hiru:atghigu', 
    'yo:ubeki', 
    'yo:ubekiki', 
    'yo:ubek' 
] 

for word in tests: 
    s = re.sub(r'([^aeiou]*[aeiou][^aeiou]*):((?:[^aeiou]*[aeiou]){3}[^aeiou]*)$', r'\1\2', word) 
    print '{} > {}'.format(word, s) 
+0

'[^ aeiou]' corrisponde a spazi, line feeds, altri due punti e segni di punteggiatura. – dawg

1

È statali che si prendono di mira una parola contro una linea, quindi prima serie ancore a che fare solo con le parole:

\b[regex will go here]\b 
^     ^ assert a word boundary 

Avanti, due punti preceduto da e seguita da un [aeiou] con altri due [aeiou] nella parte successiva ai due punti. Presumo che il caso sia indipendente?

(?i)(\b\w+[aeiou]):((?:[aeiou][^aeiou\s\W]*){3}\b) 
           ^match a character that is NOT vowel, space or not a 
             ^ \W=[^a-zA-Z0-9_] 

Demo

(Si noti l'uso di [^aeiou\W] che è lettere consonanti, numeri e _ ma non altri personaggi Demo.)

Python demo:

import re 

tests={ 
    'matches':[ 
     'we:aanyoh', 
     'hiru:atghigu', 
     'yo:ubeki' 
     ], 
    'no match':[ 
     'wz:ubeki', 
     'we:a anyoh', 
     'yo:ubek', 
     'hiru:atghiguu' 
    ]  
} 

for k, v in tests.items(): 
    print k 
    for e in v: 
     s=re.sub(r'(?i)(\b\w+[aeiou]):((?:[aeiou][^aeiou\s\W]*){3}\b)', r'\1\2', e) 
     print '\t{} > {}'.format(e, s) 

Prints:

matches 
    we:aanyoh > weaanyoh 
    hiru:atghigu > hiruatghigu 
    yo:ubeki > youbeki 
no match 
    wz:ubeki > wz:ubeki 
    we:a anyoh > we:a anyoh 
    yo:ubek > yo:ubek 
    hiru:atghiguu > hire:atghiguu 

Questo gestirà solo le parole con un singolo punto.Se vuoi abbinare parole che hanno più punti, ma hanno lo stesso modello, modifica il modello LH per avere la classe di caratteri che include i due punti e un'ancora che non è \b.

Esempio: (?i)(^[\w:]+[aeiou]):((?:[aeiou][^aeiou\s\W]*){3}\b)

-1

Roundup (io ho usato una vocale di capitale per indicare dove nella parola la sostituzione dovrebbe avvenire). Fammi sapere se vuoi che aggiunga altre stringhe di prova.

import re 

strings = [ 
    'wE:aanyoh', 
    'hirU:atghigu', 
    'yO:ubeki', 

    'xE:aaa', 
    'xx:aaa', 
    'xa:aaaxA:aaa', 
    'xa:aaaxA:aaaxx', 
    'xa:aaaxA:aaxax', 
    'a:aaaxA:aaxax', 
    'e:aeixA:aexix', 
] 


pattern = r""" 
    (
     .* 
     [aeiou] 
    ) 
    : 
    (
     [aeiou] 
     .*? 
     [aeiou] 
     .*? 
     [aeiou] 
    ) 
""" 

template = "{:>15}: {}" 
for string in strings: 
    print(
     template.format('original', string) 
    ) 

    print(template.format('Alexander:', 
     re.sub(ur"(?<=[aeiou]):(?=[aeiou]([^aeiou]*[aeiou]){2}[^aeiou]*$)", ur'', string, flags=re.I) 
    )) 

    print(template.format('lonut:', 
     re.sub(ur"([aeiou]):([aeiou])([^\Waeiou]*[aeiou][^\Waeiou]*[aeiou][^\Waeiou]*)$", ur'\1\2\3', string, flags=re.I) 
    )) 

    print(template.format('Tom Zych:', 
     re.sub(r'([^aeiou]*[aeiou][^aeiou]*):((?:[^aeiou]*[aeiou]){3}[^aeiou]*)$', r'\1\2', string, flags=re.I) 
    )) 

    print(template.format('Jeff Y:', 
     re.sub(ur"([aeiou]):(([aeiou][^aeiou]*){3})$", ur'\1\2', string, flags=re.I) 
    )) 

    print(template.format('7stud:', 
     re.sub(pattern, r'\1\2', string, count=1, flags=re.X|re.I) 
    )) 

    print("\n") 

 original: wE:aanyoh 
    Alexander:: wEaanyoh 
     lonut:: wEaanyoh 
     Tom Zych:: wEaanyoh 
     Jeff Y:: wEaanyoh 
     7stud:: wEaanyoh 


     original: hirU:atghigu 
    Alexander:: hirUatghigu 
     lonut:: hirUatghigu 
     Tom Zych:: hirUatghigu 
     Jeff Y:: hirUatghigu 
     7stud:: hirUatghigu 


     original: yO:ubeki 
    Alexander:: yOubeki 
     lonut:: yOubeki 
     Tom Zych:: yOubeki 
     Jeff Y:: yOubeki 
     7stud:: yOubeki 


     original: xE:aaa 
    Alexander:: xEaaa 
     lonut:: xEaaa 
     Tom Zych:: xEaaa 
     Jeff Y:: xEaaa 
     7stud:: xEaaa 


     original: xx:aaa 
    Alexander:: xx:aaa 
     lonut:: xx:aaa 
     Tom Zych:: xx:aaa 
     Jeff Y:: xx:aaa 
     7stud:: xx:aaa 


     original: xa:aaaxA:aaa 
    Alexander:: xa:aaaxAaaa 
     lonut:: xa:aaaxAaaa 
     Tom Zych:: xa:aaaxAaaa 
     Jeff Y:: xa:aaaxAaaa 
     7stud:: xa:aaaxAaaa 


     original: xa:aaaxA:aaaxx 
    Alexander:: xa:aaaxAaaaxx 
     lonut:: xa:aaaxAaaaxx 
     Tom Zych:: xa:aaaxAaaaxx 
     Jeff Y:: xa:aaaxAaaaxx 
     7stud:: xa:aaaxAaaaxx 


     original: xa:aaaxA:aaxax 
    Alexander:: xa:aaaxAaaxax 
     lonut:: xa:aaaxAaaxax 
     Tom Zych:: xa:aaaxAaaxax 
     Jeff Y:: xa:aaaxAaaxax 
     7stud:: xa:aaaxAaaxax 


     original: a:aaaxA:aaxax 
    Alexander:: a:aaaxAaaxax 
     lonut:: a:aaaxAaaxax 
     Tom Zych:: a:aaaxAaaxax 
     Jeff Y:: a:aaaxAaaxax 
     7stud:: a:aaaxAaaxax 


     original: e:aeixA:aexix 
    Alexander:: e:aeixAaexix 
     lonut:: e:aeixAaexix 
     Tom Zych:: e:aeixAaexix 
     Jeff Y:: e:aeixAaexix 
     7stud:: e:aeixAaexix 
+0

nel tuo pattern - '[aeiou]. *? [Aeiou]. *? [Aeiou]' - vowel seguito da qualsiasi cosa? Non è questo che consente centinaia di vocali? I tuoi casi di test sembrano testare solo i casi in cui ci sono esattamente tre vocali nel testo dopo il colon. – TessellatingHeckler

+0

@TessellatingHeckler, Yep. :( – 7stud

+0

Non capisco perché tu Stai comparando altre risposte. Ti dispiacerebbe spiegare qual è la differenza? – Mariano

Problemi correlati