Domanda

Sto cercando di implementare la funzione di escape delle stringhe con regex e backreference di Python e non sembra che funzioni molto bene.Sono sicuro che sto sbagliando qualcosa ma non riesco a capire cosa...

>>> import re
>>> mystring = r"This is \n a test \r"
>>> p = re.compile( "\\\\(\\S)" )
>>> p.sub( "\\1", mystring )
'This is n a test r'
>>> p.sub( "\\\\\\1", mystring )
'This is \\n a test \\r'
>>> p.sub( "\\\\1", mystring )
'This is \\1 a test \\1'

Vorrei sostituire \\[char] con \[char], ma i riferimenti all'indietro in Python non sembrano seguire le stesse regole che seguono in ogni altra implementazione che abbia mai usato.Qualcuno potrebbe far luce?

È stato utile?

Soluzione

Non è quello che fa il secondo esempio di Anders?

In 2.5 c'è anche una codifica stringa-escape che puoi applicare:

>>> mystring = r"This is \n a test \r"
>>> mystring.decode('string-escape')
'This is \n a test \r'
>>> print mystring.decode('string-escape')
This is 
 a test 
>>> 

Altri suggerimenti

Beh, penso che potresti aver perso r o contato male le barre rovesciate ...

"\\n" == r"\n"

>>> import re
>>> mystring = r"This is \\n a test \\r"
>>> p = re.compile( r"[\\][\\](.)" )
>>> print p.sub( r"\\\1", mystring )
This is \n a test \r
>>>

Che, se ho capito, è quello che è stato richiesto.

Sospetto che la richiesta più comune sia questa:

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'}
>>> p = re.compile(r"[\\]([nrfv])")
>>> print p.sub(lambda mo: d[mo.group(1)], mystring)
This is \
 a test \
>>>

Lo studente interessato dovrebbe leggere anche Reflections on Trusting Trust " , in cui il nostro eroe usa un esempio simile per spiegare i pericoli di compilatori fiduciosi che non hai avviato autonomamente dal codice macchina.

L'idea è che leggerò una stringa con escape e la annullerò (una caratteristica in particolare carente da Python, per la quale non dovresti ricorrere alle espressioni regolari per prima cosa). Purtroppo non sono stato ingannato dalle barre rovesciate ...

Un altro esempio illustrativo:

>>> mystring = r"This is \n ridiculous"
>>> print mystring
This is \n ridiculous
>>> p = re.compile( r"\\(\S)" )
>>> print p.sub( 'bloody', mystring )
This is bloody ridiculous
>>> print p.sub( r'\1', mystring )
This is n ridiculous
>>> print p.sub( r'\\1', mystring )
This is \1 ridiculous
>>> print p.sub( r'\\\1', mystring )
This is \n ridiculous

Quello che mi piacerebbe stampare è

This is 
ridiculous

Sei stato ingannato dalla rappresentazione di Python della stringa del risultato. L'espressione Python:

'This is \\n a test \\r'

rappresenta la stringa

This is \n a test \r

che penso sia quello che volevi. Prova ad aggiungere 'print' davanti a ciascuna delle tue chiamate p.sub () per stampare la stringa effettiva restituita invece di una rappresentazione Python della stringa.

>>> mystring = r"This is \n a test \r"
>>> mystring
'This is \\n a test \\r'
>>> print mystring
This is \n a test \r

Marco; il suo secondo esempio richiede che ogni carattere di escape sia inizialmente gettato in un array, il che genera un KeyError se la sequenza di escape non si trova nell'array. Morirà su qualsiasi cosa tranne i tre caratteri forniti (prova \ v) e enumerare ogni possibile sequenza di escape ogni volta che vuoi annullare lo scappamento di una stringa (o mantenere un array globale) è davvero una pessima soluzione. Analogamente a PHP, sta usando preg_replace_callback () con un lambda invece di preg_replace () , che è assolutamente superfluo in questa situazione.

Mi dispiace se me ne vado come un coglione, sono completamente frustrato con Python. Questo è supportato da ogni altro motore di espressione regolare che io abbia mai usato e non riesco a capire perché non funzioni.

Grazie per aver risposto; la funzione string.decode ('string-escape') è esattamente quello che stavo cercando inizialmente. Se qualcuno ha una soluzione generale al problema del backreference di regex, sentiti libero di pubblicarlo e lo accetterò anche come risposta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top