2015-12-25 13 views
6

Próbowałem następujące regex, ale pasuje do wszystkich podwójnych cudzysłowach:Czy istnieje sposób na dopasowanie podwójnych cudzysłowów do dwóch podwójnych cudzysłowów?

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

Oto próbka tekstu:

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

Wzór Chcę dopasować jest cudzysłów pomiędzy podwójne cytaty w line 2

+1

Może [(?! <\ S * [[,] \ s *) (?! [\]]) '" '] (http://regexstorm.net/tester?p=(%3f%3c!%5cs*%5b%5b%2c%5d%5cs*)%22(%3f!%5b%2c%5c%5d%5d) i i =% 5b% 22my + samochody + ostatnie + noc% 22% 2c% 0d% 0a% 22Burger% 22% 2c% 22Dekaf% 22 + koszula% 22% 2c% 0d% 0a% 22Mocha% 22% 2c% 22marsmallows% 22% 2c% 0d% 0a% 22Coffee + Mission% 22% 5d & r =). –

+0

@stribizhev Wielkie dzięki. Działa to jak czar do strony z wyrażeniami regularnymi, które podałeś, ale kiedy próbuję tego w moim kodzie Ruby, to działa inaczej i to nie działa. Przypuszczam, że Regex ma inny synt topór dla ruby, aby go dopasować. – 0bserver07

Odpowiedz

4

Zgodnie z ogólną zasadą, powiedziałbym: nr.

Biorąc pod uwagę ciąg:

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

Jak zdecydować, który \" jest zbędny (nie pasujące do całości)? Czy jest to jedna po Burger, jedna po Decaf lub jedna po shirt? Lub jedno przed którymś z tych słów? Uważam, że wybór jest arbitralny.

Chociaż w konkretnego przykładu wydaje się, że chcesz wszystko \" które nie sąsiadują z przecinkiem.

Te można znaleźć następującą regexp:

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

Zaczynamy \\" (backslash następnie podwójny cudzysłów) w centrum.

Następnie używamy negatywnej uprzedniej do odrzucenia wszystkich dopasowań, po których następuje przecinek lub zamykający nawias kwadratowy.

Następnie używamy negatywnego lookbehind, aby odrzucić wszystkie mecze, które mają miejsce po przecinku lub nawiasem otwierającym.

Silnik Regexpa, którego użyłem, nie radzi sobie z naprzemiennymi wewnętrznymi stwierdzeniami. Aby obejść ten problem, wykorzystuję fakt, że obejścia są dopasowaniami o zerowej długości i zaczynam negatywny lookbehind, który dopasowuje początek linii na początku wyrażenia.

Proof (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

Dzięki @ Mirosław Zalewski, ta praca i szczegóły są bardzo przydatne, aby zrozumieć, czego mi brakowało we wzorcu. Myślałem o tym samym problemie, ale to jest po rozwiązaniu jak 3 inne dziwne wzory. – 0bserver07

1

Załóżmy, że format Twojego ciąg musi być tak:

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

Sposób, aby wiedzieć, czy podwójny cudzysłów jest zamknięcie cudzysłów jest sprawdzenie, czy po nim następuje przecinek lub zamykający nawias kwadratowy. Aby znaleźć podwójny cudzysłów ujęty w cudzysłowy, należy dopasować wszystkie dobrze sformatowane elementy od początku do nieoczekiwanego cudzysłowu.

Przykład aby znaleźć pierwszą zamkniętą cytat (jeśli istnieje):

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

demo

Ale to działa tylko na jednym zamkniętym środki we wszystkich łańcucha i nie jest przydatna, jeśli chcesz znaleźć wszystkie.

znaleźć wszystkie cytaty:

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

demo

+0

Wielkie dzięki @Casmir! Bardzo pomocny również! – 0bserver07

Powiązane problemy