Questa domanda è stata posta e ha risposto molte volte in precedenza. Alcuni esempi: [1], [2]. Ma non sembra essere qualcosa di più generale. Quello che sto cercando è un modo per dividere le stringhe in virgole che non siano tra virgolette o coppie di delimitatori. Per esempio:Suddivisione delle stringhe delimitate da virgola in python
s1 = 'obj<1, 2, 3>, x(4, 5), "msg, with comma"'
dovrebbe essere diviso in una lista di tre elementi
['obj<1, 2, 3>', 'x(4, 5)', '"msg, with comma"']
Il problema ora è che questo può diventare più complicata dal momento che siamo in grado di guardare in coppie di <>
e ()
.
s2 = 'obj<1, sub<6, 7>, 3>, x(4, y(8, 9), 5), "msg, with comma"'
che dovrebbe essere diviso in:
['obj<1, sub<6, 7>, 3>', 'x(4, y(8, 9), 5)', '"msg, with comma"']
La soluzione ingenua senza l'utilizzo di espressioni regolari è quello di analizzare la stringa, cercando per i personaggi ,<(
. Se vengono trovati <
o (
, iniziamo a contare la parità. Possiamo dividere solo una virgola se la parità è zero. Per esempio diciamo che vogliamo dividere s2
, possiamo iniziare con parity = 0
e quando raggiungiamo s2[3]
abbiamo incontrare <
che aumenterà la parità di 1. La parità diminuisce solo quando incontra >
o )
e aumenterà quando incontra <
o (
. Mentre la parità non è 0, possiamo semplicemente ignorare le virgole e non fare alcuna suddivisione.
La domanda qui è, c'è un modo per questo rapidamente con regex? Stavo davvero esaminando questo solution ma questo non sembra che copra gli esempi che ho dato.
una funzione più generale sarebbe qualcosa di simile:
def split_at(text, delimiter, exceptions):
"""Split text at the specified delimiter if the delimiter is not
within the exceptions"""
Alcuni usi sarebbe come questo:
split_at('obj<1, 2, 3>, x(4, 5), "msg, with comma"', ',', [('<', '>'), ('(', ')'), ('"', '"')]
Sarebbe regex essere in grado di gestire questo o è necessario creare una specializzati parser?
Le espressioni regolari non vi aiuterà in questo caso, poiché la lingua (es. un gruppo di stringhe) che stai cercando di analizzare non è regolare. Dato che si consente l'annidamento arbitrario dei tag, non esiste un modo semplice per regex l'uscita da questo. –
Regex non può in effetti gestire questo problema e non lo si vorrebbe. La complessità è lineare al minimo, quindi è sempre necessario ottenere prestazioni migliori con il controllo di parità. Non devi costruirlo da solo però. Il modulo 'csv' di Python fa un sacco di legwork. –
Argh, non dire che regex non può gestirlo! Forse il sapore del pitone non poteva, ma altri sapori come PCRE potevano farlo! Questo è [a prova] (http://regex101.com/r/wU7lC9), potremmo anche essere fantasiosi e usare pattern ricorsivi per tenere in considerazione nested '<>()' – HamZa