2010-09-02 12 views
14

c'è un modo utilizzando una regex per abbinare una serie di ripetere di personaggi? Per esempio:ripetendo più personaggi espressione regolare

ABCABCABCABCABC

ABC{5}

So che è sbagliato. Ma c'è qualcosa per abbinare questo effetto?

Aggiornamento:

si può utilizzare nidificato i gruppi di cattura? Così Qualcosa di simile (?<cap>(ABC){5})?

risposta

34

Racchiudere l'espressione regolare che si desidera ripetere tra parentesi. Per esempio, se si vuole 5 ripetizioni di ABC:

(ABC){5} 

Oppure, se volete un qualsiasi numero di ripetizioni (0 o più):

(ABC)* 

o uno o più ripetizioni:

(ABC)+ 

modifica per rispondere all'aggiornamento

Le parentesi nelle espressioni regolari fanno due cose; si raggruppano una sequenza di elementi in un'espressione regolare, in modo che è possibile applicare un operatore per un'intera sequenza invece che solo l'ultima voce, e catturare i contenuti di quel gruppo in modo da poter estrarre la sottostringa che corrispondeva con quella sottoespressione nella regex.

Puoi parentesi nido; sono contati dal primo paren di apertura. Per esempio:

>>> re.search('[0-9]* (ABC(...))', '123 ABCDEF 456').group(0) 
'123 ABCDEF' 
>>> re.search('[0-9]* (ABC(...))', '123 ABCDEF 456').group(1) 
'ABCDEF' 
>>> re.search('[0-9]* (ABC(...))', '123 ABCDEF 456').group(2) 
'DEF' 

Se volete evitare la cattura quando si esegue il raggruppamento, è possibile utilizzare (?:. Questo può essere utile se non si desidera parentesi che si sta solo usando per raggruppare una sequenza allo scopo di applicare un operatore per cambiare la numerazione delle tue partite. È anche più veloce.

>>> re.search('[0-9]* (?:ABC(...))', '123 ABCDEF 456').group(1) 
'DEF' 

Quindi per rispondere alla tua aggiornamento, sì, è possibile utilizzare i gruppi di cattura nidificati, o addirittura evitare la cattura con il gruppo interno a tutti:

>>> re.search('((?:ABC){5})(DEF)', 'ABCABCABCABCABCDEF').group(1) 
'ABCABCABCABCABC' 
>>> re.search('((?:ABC){5})(DEF)', 'ABCABCABCABCABCDEF').group(2) 
'DEF' 
+2

Vorrei usare + qui anziché *, perché * corrisponderà a 0 occorrenze di (ABC). – Robusto

+4

(ABC) {3,5} anche per una serie di ripetizioni –

+0

Oh duh. Stavo pensando() è usato solo per quella roba di cattura per qualche ragione. Ma questo ha un senso. Scelto per essere il primo – Falmarri

3

(ABC){5} dovrebbe funzionare per voi

1

parentesi "()" sono usati per raggruppare caratteri ed espressioni all'interno di espressioni regolari più grandi e complesse. I quantificatori che seguono immediatamente il gruppo si applicano all'intero gruppo.

(ABC){5} 
3

ABC {5} corrisponde a ABCCCCC. Per abbinare 5 ABC, devi usare (ABC) {5}. Le parentesi sono usate per raggruppare un insieme di caratteri. È inoltre possibile impostare un intervallo per le occorrenze come (ABC) {3,5}, che corrisponde ABCABCABC, abcabcabcabc e ABCABCABCABCABC.

(ABC) {1,} indica 1 o più ripetizioni che è esattamente lo stesso come (ABC) +.

(ABC) {0,} significa 0 o più ripetizioni che è esattamente la stessa di (ABC) *.

0

Per quanto riguarda l'aggiornamento per il Question-

È possibile nidificare i gruppi di cattura. L'indice del gruppo di cattura viene incrementato per paren aperto.

(((ABC)*)(DEF)*) 

alimentazione che regex ABCABCABCDEFDEFDEF, gruppo di cattura 0 partite tutta la faccenda, 1 è anche il tutto, 2 è ABCABCABC, 3 è ABC, e 4 è DEF (perché la stella è al di fuori del gruppo di cattura) .

Se si dispone di variazione all'interno di un gruppo di cattura e una ripetizione appena fuori, allora le cose possono diventare un po 'traballante, se non ti aspetti che ...

(a[bc]*c)* 

quando abbbcccabbc alimentato restituirà l'ultima corrisponde come gruppo di acquisizione 1, in questo esempio solo l'abbc, poiché il gruppo di acquisizione viene ripristinato con l'operatore di ripetizione.