2015-12-25 14 views
6

Ho provato la seguente espressione regolare, ma corrisponde a tutti i doppi apici:C'è un modo per far corrispondere le virgolette doppie tra due virgolette doppie?

(?>(?<=(")|))"(?(1)(?!")) 

Ecco un esempio del testo:

"[\"my cars last night\", 
\"Burger\",\"Decaf\" shirt\", 
\"Mocha\",\"marshmallows\", 
\"Coffee Mission\"]" 

Il modello che voglio abbinare è il doppio apice tra il doppi apici in line 2

+1

Forse [(?! <\ S * [[,] \ s *) (?! [, \]]) '" '] (http://regexstorm.net/tester?p=(%3f%3c!%5cs*%5b%5b%2c%5d%5cs*)%22(%3f!%5b%2c%5c%5d%5d) & i =% 5b% 22my + auto + ultima + night% 22% 2c% 0d% 0a% 22Burger% 22% 2c% 22Decaf% 22 + camicia% 22% 2c% 0d% 0a% 22Mocha% 22% 2c% 22marshmallows% 22% 2c% 0d% 0a% 22Coffee + Missione% 22% 5d & r =). –

+0

@stribizhev Grazie mille. Funziona come un incantesimo per il sito di espressioni regolari che hai allineato, ma quando provo questo nel mio codice Ruby funziona diversamente e non lo raccoglie Credo che il Regex abbia una sincronizzazione diversa ascia per rubino per abbinarla. – 0bserver07

risposta

4

Come una regola generale, direi: no.

data una stringa:

\"Burger\" \"Decaf\" shirt\" 

Come si fa a decidere che \" è superfluo (non-matching)? E 'questo dopo Burger, uno dopo Decaf o uno dopo shirt? O uno prima di una di queste parole? Credo che la scelta sia arbitraria.

Sebbene in il proprio esempio specifico sembra che si desidera tutto il \" che non sono adiacenti alla virgola.

Questi possono essere trovati seguendo regexp:

(?<!^)(?<![,\[])\\"(?![,\]]) 

Iniziamo con \\" (backslash seguito da virgolette) al centro.

Quindi usiamo il lookahead negativo per scartare tutte le partite seguite da virgola o parentesi quadra chiusa.

Quindi usiamo il lookbehind negativo per scartare tutte le corrispondenze che si verificano dopo virgola o parentesi di apertura.

Il motore Regexp che ho usato non può far fronte all'alternanza all'interno di dichiarazioni di lookaround. Per ovviare a questo problema, traggo vantaggio dal fatto che i lookaround sono partite a lunghezza zero e io antepongo la ricerca negativa che corrisponde all'inizio della riga all'inizio dell'espressione.

Proof (in Perl):

$ cat test 
"[\"my cars last night\", 
\"Burger\",\"Decaf\" shirt\", 
\"Mocha\",\"marshmallows\", 
\"Coffee Mission\"]" 
$ perl -n -e '$_ =~ s/(?<!^)(?<![,\[])\\"(?![,\]])/|||/g; print $_' test 
"[\"my cars last night\", 
\"Burger\",\"Decaf||| shirt\", 
\"Mocha\",\"marshmallows\", 
\"Coffee Mission\"]" 
+0

Grazie a Mirosław Zalewski, questo funziona e i dettagli sono molto utili per capire cosa mi mancava dal modello. Ho pensato allo stesso problema, ma questo è dopo aver risolto come altri 3 modelli strani. – 0bserver07

1

Supponiamo che il formato della stringa deve essere come questo:

["item1", "item2", ... "itemN"] 

Il modo per sapere se un doppio apice è una doppia citazione chiusura è controllare se è seguito da una virgola o da una parentesi quadra chiusa. Per trovare una virgoletta doppia racchiusa tra virgolette doppie, è necessario abbinare tutti gli elementi ben formattati dall'inizio fino a un preventivo imprevisto.

Esempio per trovare la prima citazione in dotazione (se esiste):

(?:"[^"]*",\s*)*+"[^"]*\K" 

demo

Ma questo funziona solo per un preventivo racchiuso in tutta la stringa e non è utile se si desidera trova tutti loro.

trovare tutte le citazioni:

(?:\G(?!\A)|(?:\A[^"]*|[^"]*",\s*)(?:"[^"]*",\s*)*+")[^"]*\K"(?!\s*[\],]) 

demo

+0

Grazie mille @Casmir! Molto utile pure! – 0bserver07

Problemi correlati