HOWTO · Python
Python Trova stringa nel file
Il tutorial mostra come cercare una stringa in un file di testo in Python.
In questa pagina
Per trovare una sottostringa letterale in un file di testo, usa read() con in per ottenere un risultato booleano, readlines() per esaminare le righe corrispondenti oppure find() per trovare la posizione di un carattere. Per file di grandi dimensioni o dati orientati ai byte, mmap consente di effettuare una ricerca basata su un file mappato. Gli esempi usano lo stesso breve testo per permetterti di confrontarne i risultati e i compromessi. Ogni esempio è eseguibile; l’output mostrato corrisponde all’esecuzione fornita.
Cercare nel contenuto di un file con read() e in
Il metodo read() restituisce il contenuto rimanente del file come un’unica stringa. Usa l’operatore in di Python per verificare se quella stringa contiene il testo letterale che cerchi. L’espressione produce True o False, un risultato utile quando vuoi soltanto sapere se la sottostringa è presente.
È un approccio diretto, ma prima della ricerca carica l’intero file in memoria. È adatto a file di testo piccoli o medi e ai casi in cui ti serve anche il contenuto completo. Se il file è troppo grande per essere mantenuto comodamente in memoria, scegli invece un approccio basato sulle righe o su una mappatura.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("status=ready\nowner=Sam\n", encoding="utf-8")
with path.open(encoding="utf-8") as file:
found = "ready" in file.read()
print(found)
True
Cercare riga per riga con readlines()
Il metodo readlines() restituisce una lista con le righe del file, comprese le terminazioni di riga quando presenti. Puoi verificare ogni riga con in e fermarti alla prima corrispondenza. È utile quando ti interessa la riga che contiene la corrispondenza, per esempio per decidere quale record visualizzare o elaborare.
Anche se il ciclo può fermarsi in anticipo, readlines() ha già caricato tutte le righe in una lista. Di conseguenza, l’uso di memoria cresce con le dimensioni del file. Per elaborare progressivamente un file grande, iteralo direttamente mentre è aperto con for line in file: in questo modo eviti di creare la lista completa, mantenendo la stessa logica di ricerca riga per riga.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("status=ready\nowner=Sam\n", encoding="utf-8")
with path.open(encoding="utf-8") as file:
for line in file.readlines():
if "owner" in line:
print(line.rstrip())
break
owner=Sam
Usare find() per ottenere la posizione di una corrispondenza
Usa il metodo find() sulla stringa restituita da read() quando ti serve l’indice iniziale della corrispondenza, anziché una semplice risposta sì o no. L’indice parte da zero: se la corrispondenza è all’inizio, il risultato è 0; se si trova più avanti, il risultato ne indica la posizione nella stringa. Se non ci sono corrispondenze, find() restituisce -1. Controlla esplicitamente questo valore invece di interpretare ogni risultato come booleano, perché in Python 0 è considerato falso.
La posizione restituita conta i caratteri della stringa Python decodificata, non i byte del file. Se il file contiene caratteri non ASCII, aprilo specificando una codifica appropriata. Se ti servono offset in byte o il contenuto è binario, usa una ricerca basata sui byte, per esempio mmap con un pattern di byte.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_text("status=ready\nowner=Sam\n", encoding="utf-8")
with path.open(encoding="utf-8") as file:
contents = file.read()
position = contents.find("ready")
print(position)
print(contents.find("missing"))
7
-1
Cercare in un file di grandi dimensioni con mmap
Il modulo mmap mappa un file in un oggetto simile a una sequenza di byte, che consente di cercare senza creare prima una stringa Python contenente l’intero file. Può essere utile con file grandi, ma non garantisce una ricerca più veloce: le prestazioni dipendono dal file, dal supporto di memorizzazione, dal sistema operativo e dal modo in cui si accede ai dati. La mappatura usa anche risorse del sistema operativo: ricordati di chiuderla quando hai finito.
Cerca nella mappatura usando un pattern di byte come b"ready". A differenza degli esempi sul testo, questa ricerca opera sui byte codificati e restituisce un offset in byte. Il pattern deve essere composto da byte: una stringa normale come "ready" è un tipo diverso. Questo esempio usa byte UTF-8 per lo stesso testo ASCII e apre il file in modalità binaria.
Esegui questo esempio:
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
import mmap
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
path.write_bytes(b"status=ready\nowner=Sam\n")
with path.open("rb") as file:
with mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as mapped:
print(mapped.find(b"ready"))
7
Scegliere l’approccio giusto
Scegli read() con in quando basta sapere se il testo è presente e il contenuto completo entra comodamente in memoria. Scegli readlines() quando ti serve una lista di righe da esaminare o conservare; ricorda che la lista contiene l’intero file. Per file di testo grandi le cui righe possono essere elaborate singolarmente, itera direttamente sull’oggetto file invece di memorizzare tutte le righe.
Scegli find() quando ti interessa la posizione in caratteri della prima corrispondenza letterale. Per verificare che non sia presente, confronta il risultato con -1; considera 0 una posizione valida. Scegli mmap quando è appropriata una ricerca sui byte basata su un file mappato e ti serve l’offset in byte: codifica il testo da cercare come byte e non dare per scontato che la mappatura sia sempre più veloce. Questi metodi cercano testo letterale. Se invece ti servono pattern, la normalizzazione delle maiuscole e minuscole o tutte le occorrenze, scegli un metodo adatto a quel requisito.