string - Lavorare con il testo

Scopo Contiene costanti e classi per lavorare con il testo
Versione Python 2.5

Il modulo string è presente fin dalle prime versioni di Python. Nella versione 2.0 molte delle funzioni precedentemente implementate solo nel modulo sono state spostate come metodi degli oggetti str ed unicode. Sono ancora disponibili le versioni per compatibilità di queste funzioni, ma il loro uso è deprecato ed esse verranno abbandonate in Python 3.0. Il modulo string contiene comunque parecchie costanti e classi utili per lavorare con oggetti stringa ed unicode e questa discussione si concentrerà su di essi.

Costanti

Le costanti nel modulo stringa possono essere usate per specificare categorie di caratteri come ascii_letters e digits (lettere ASCII e cifre - n.d.t.). Alcune delle costanti dipendono dalla localizzazione, come lowercase,così che i valori siano modificati per riflettere le impostazioni di lingua dell'utente. Altre tipo hexdigits non subiscono mutamenti quando cambia la localizzazione.

import string

for n in dir(string):
    if n.startswith('_'):
        continue
    v = getattr(string, n)
    if isinstance(v, basestring):
        print '%s=%s' % (n, repr(v))
        print

La maggior parte dei nomi delle costanti sono autoesplicativi (ovviamente per la lingua inglese - n.d.t.).

$ python string_constants.py
ascii_letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

ascii_lowercase='abcdefghijklmnopqrstuvwxyz'

ascii_uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

digits='0123456789'

hexdigits='0123456789abcdefABCDEF'

letters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

lowercase='abcdefghijklmnopqrstuvwxyz'

octdigits='01234567'

printable='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

punctuation='!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

whitespace='\t\n\x0b\x0c\r '

Funzioni

Ci sono due funzioni che non sono state spostate dal modulo string: capwords() trasforma in maiuscolo tutte le iniziali di ogni parola in una stringa.

import string

s = 'The quick brown fox jumped over the lazy dog.'

print s
print string.capwords(s)

Il risultato è identico a quello che si sarebbe ottenuto chiamando split() trasformando la prima lettera di ogni parola nella lista ritornata in maiuscolo, quindi chiamando join() per unire il risultato.

$ python string_capwords.py
The quick brown fox jumped over the lazy dog.
The Quick Brown Fox Jumped Over The Lazy Dog.

L'altra funzione crea delle tabelle di trascodifica che possono essere usate con il metodo translate() per trasformare un insieme di caratteri in un altro

import string

leet = string.maketrans('abegiloprstz', '463611092572')

s = 'The quick brown fox jumped over the lazy dog.'

print s
print s.translate(leet)

In questo esempio, alcune lettere sono sostituite dai numeri ad esse corrispondenti nella notazione I33t

$ python string_maketrans.py
The quick brown fox jumped over the lazy dog.
Th3 qu1ck 620wn f0x jum93d 0v32 7h3 142y d06.

Template

I template di stringa furono aggiunti in Python 2.4 come parte di PEP 292 e sono da intendersi come un'alternativa alla sintassi di interpolazione built-in. Con l'interpolazione di string.Template, le variabili sono identificate dal nome preceduto da $ (es. $var) oppure, se necessario per isolarle dal testo circostante, possono anche essere racchiuse tra parentesi graffe (es. ${var}).

L'esempio confronta un semplice template con una impostazione di interpolazione di stringa similare.

import string

values = { 'var':'foo' }

t = string.Template("""
$var
$$
${var}iable
""")

print 'TEMPLATE:', t.substitute(values)

s = """
%(var)s
%%
%(var)siable
"""

print 'INTERPOLAZIONE:', s % values

Come si vede, in entrambi i casi il carattere trigger - quello che precede il nome di variabile da interpolare - $ oppure %) viene interpretato letteralmente ripetendolo due volte.

$ python string_template.py
TEMPLATE:
foo
$
fooiable

INTERPOLAZIONE:
foo
%
fooiable

Una differenza chiave tra i template e l'interpolazione di stringa standard è che il tipo degli argomenti non viene preso in considerazione. I valori sono convertiti in stringhe e le stringhe sono inserite nel risultato. Non è disponibile alcuna opzione di formattazione. Ad esempio, non vi è modo di controllare il numero di cifre usato per rappresentare un valore a virgola mobile.

Un vantaggio, comunque, è che usando il metodo safe_substitute(), è possibile evitare le eccezioni se non tutti i valori richiesti dal template sono passati come argomenti.

import string

values = { 'var':'foo' }

t = string.Template("$var esiste ma $mancante non è fornito")

try:
    print 'TEMPLATE:', t.substitute(values)
except KeyError, err:
    print 'ERRORE:', str(err)

print 'TEMPLATE:', t.safe_substitute(values)

Visto che non esiste alcun valore per 'mancante' nel dizionario dei valori, viene sollevata una eccezione KeyError da substitute(). Invece che sollevare l'errore safe_substitute() lo cattura e lascia la variabile immutata nel testo.

$ python string_template_mancante.py
TEMPLATE: ERRORE: 'mancante'
TEMPLATE: foo esiste ma $mancante non è fornito

Template avanzati

Se la sintassi predefinita di string.Template non è di proprio gradimento, si può modificarne il comportamento correggendo i modelli dell'espressione regolare che usa per trovare i nomi delle variabili nel corpo del template. Un modo semplice per fare questo è modificare gli attributi di classe delimiter e idpattern.

import string

class MyTemplate(string.Template):
    delimiter = '%'
    idpattern = '[a-z]+_[a-z]+'

t = MyTemplate('%% %with_underscore %notunderscored')
d = { 'with_underscore':'replaced',
      'notunderscored':'not replaced',
      }

print t.safe_substitute(d)

In questo esempio, gli identificativi delle variabili devono includere un carattere di sottolineatura da qualche parte nel mezzo, così che %notunderscored non sia sostituito.

$ python string_template_advanced.py

% replaced %notunderscored

Per modifiche più complesse si può sovrascrivere l'attributo pattern e definire una espressione regolare completamente nuova. Il modello fornito deve contenere 4 gruppi distinti per catturare il delimitatore da stampare letteralmente, il nome della variabile, una versione tra parentesi graffe del nome della variabile ed il delimitatore non valido.

Diamo un'occhiata al modello predefinito:

import string

t = string.Template('$var')
print t.pattern.pattern

Visto che t.pattern è una espressione regolare compilata, dobbiamo accedere al suo attributo pattern per vedere la stringa reale

$ python string_template_defaultpattern.py

    \$(?:
      (?P\$) |   # Escape sequence of two delimiters
      (?P[_a-z][_a-z0-9]*)      |   # delimiter and a Python identifier
      {(?P[_a-z][_a-z0-9]*)}   |   # delimiter and a braced identifier
      (?P)              # Other ill-formed delimiter exprs
    )

Se si vuole creare un nuovo tipo di template usando, ad esempio, {{var}} come sintassi della variabile, potremmo usare un modello tipo questo:

import re
import string

class MyTemplate(string.Template):
    delimiter = '{{'
    pattern = r'''
    \{\{(?:
    (?P<escaped>\{\{)|
    (?P<named>[_a-z][_a-z0-9]*)\}\}|
    (?P<braced>[_a-z][_a-z0-9]*)\}\}|
    (?P<invalid>)
    )
    '''

t = MyTemplate('''
{{{{
{{var}}
''')

print 'MATCHES:', t.pattern.findall(t.template)
print 'SUBSTITUTED:', t.safe_substitute(var='replacement')

Dobbiamo comunque fornire i modelli del nome e del nome racchiuso tra graffe, anche se sono i medesimi. Ecco il risultato:

$ python string_template_newsyntax.py
MATCHES: [('{{', '', '', ''), ('', 'var', '', '')]
SUBSTITUTED:
{{
replacement

Funzioni deprecate

Per informazioni sulle funzioni deprecate spostate nelle classi string ed unicode, fare rifermento ai Metodi Stringa nel manuale.

Vedere anche:

string
La documentazione standard della libreria per questo modulo
PEP 202
Sostituzioni di stringa più semplici
Strumenti per l'elaborazione del testo