In [29]: re.findall("([abc])+","abc")
Out[29]: ['c']
In [30]: re.findall("[abc]+","abc")
Out[30]: ['abc']
Confuso da quello raggruppato. Come fa la differenza?differenza tra due espressioni regolari: [abc] + e ([abc]) +
In [29]: re.findall("([abc])+","abc")
Out[29]: ['c']
In [30]: re.findall("[abc]+","abc")
Out[30]: ['abc']
Confuso da quello raggruppato. Come fa la differenza?differenza tra due espressioni regolari: [abc] + e ([abc]) +
Ci sono due cose che devono essere spiegate qui: il comportamento dei gruppi quantificati e la progettazione del metodo findall()
.
Nel tuo primo esempio, [abc]
corrisponde allo a
, che viene catturato nel gruppo # 1. Quindi corrisponde allo b
e lo cattura nel gruppo # 1, sovrascrivendo lo a
.Poi di nuovo con il c
, e questo è ciò che è rimasto nel gruppo # 1 alla fine della partita.
Ma è corrisponde a corrisponde all'intera stringa. Se si stesse utilizzando search()
o finditer()
, si sarebbe in grado di guardare MatchObject e vedere che group(0)
contiene abc
e group(1)
contiene c
. Ma findall()
restituisce stringhe, non MatchObjects. Se non ci sono gruppi, restituisce una lista delle partite complessive; se ci sono gruppi, l'elenco contiene tutte le acquisizioni, ma non la partita complessiva.
Quindi entrambe le espressioni regolari corrispondono all'intera stringa, ma la prima cattura e scartando singolarmente ogni carattere (che è un po 'inutile). È solo il comportamento imprevisto di findall()
che fa sembrare che stai ottenendo risultati diversi.
Il raggruppamento ha solo una diversa preferenza.
([abc])+
=> Trova uno dalla selezione. Può abbinare uno o più. Trova una e tutte le condizioni sono soddisfatte in quanto + significa 1 o più. Questo rompe la regex in due fasi.
Mentre il gruppo non raggruppato viene considerato nel suo complesso.
Questa spiegazione è completamente sbagliata. Non c'è nessun cortocircuito coinvolto. Se questa spiegazione fosse corretta, il primo 'findall' avrebbe restituito' ['a'] 'invece di' ['c'] '. – user2357112
I cortocircuiti potrebbero essere il termine sbagliato. tutte le condizioni sono soddisfatte. - cambia lingua per riflettere –
No, non è solo "cortocircuito" essere il termine sbagliato. Il meccanismo al lavoro non funziona nel modo in cui descrivi. Come un altro esempio, '^ ([abc]) + $' non dà ''abc'' neanche; [dà ancora '['c']'] (http://ideone.com/Mj9Wh2). – user2357112
input "abc"
[abc]
partita un singolo carattere => "a"
[abc]+
+ Tra uno e periodi illimitati, tante volte quanto possibile => "abc"
([abc])
gruppo di cattura ([abc]) => "a"
([abc])+
+ Un ripetuto gruppo cattura catturerà solo l'ultima iterazione => "c"
Nel primo esempio si dispone di un gruppo di catturato ripetuto che cattura solo l'ultima iterazione. Qui c
.
([abc])+
Nel secondo esempio si sta corrispondono a un singolo carattere nella lista una volta e illimitate.
[abc]+
Ecco il modo in cui vorrei pensarci. ([abc])+
sta tentando di ripetere un gruppo catturato. Quando si usa "+" dopo il gruppo di cattura, non significa che si otterranno due gruppi catturati. Quello che succede, almeno per la regex di Python e la maggior parte delle implementazioni, è che il "+" forza l'iterazione finché il gruppo di cattura non contiene solo l'ultima corrispondenza.
Se si desidera acquisire un'espressione ripetuta, è necessario invertire l'ordine di "(...)" e "+", ad es. invece di ([abc])+
utilizzare ([abc]+)
.
're.findall' lancia una chiave nell'analisi poiché' re.findall ("[abc] +", "abc") 'cattura comunque senza la parentesi (mostra la corrispondenza completa quindi ...) Prova' re .search (r '([abc]) +', 'abc'). group (1) 'e' re.search (r '([abc] +)', 'abc'). group (1) ' – dawg