Регулярное выражение соответствует запятой, которая не окружена кавычками

Я использую Clojure, так что это в контексте регулярных выражений Java.

Вот пример строки:

{:a "ab,cd, efg", :b "ab,def, egf,", :c "Conjecture"}

Важными битами являются запятые после каждой строки. Я хотел бы иметь возможность заменить их символами новой строки методом Java replaceAll. Будет регулярное выражение, которое будет соответствовать любой запятой, которая не окружена кавычками.

Если я не пойду хорошо, спросите, и я буду счастлив прояснить что-нибудь.

Изменить: извините за путаницу в заголовке. Я не просыпался очень долго.

String: {:a "ab, cd efg",} < - В этом примере запятая в конце будет сопоставлена, но те внутри цитаты не будут.

String: {:a 3, :b 3,} < - Каждая отдельная запятая соответствует.

String {:a "abcd,efg" :b "abcedg,e"} < - Каждая отдельная запятая не соответствует.

Ответы

Ответ 1

Регулярное выражение:

,\s*(?=([^"]*"[^"]*")*[^"]*$)

Матчи:

{:a "ab,cd, efg", :b "ab,def, egf,", :c "Conjecture"}
                ^                  ^
                ^                  ^

и

{:a "ab, cd efg",}
                ^
                ^

и не соответствует запятой в:

{:a "abcd,efg" :b "abcedg,e"}

Но когда могут появиться скрытые кавычки, например:

{:a "ab,\" cd efg",} // only the last comma should match

тогда решение регулярного выражения не будет работать.

Краткое пояснение регулярного выражения:

,            # match the character ','
\s*          # match a whitespace character: [ \t\n\x0B\f\r] and repeat it zero or more times
(?=          # start positive look ahead
  (          #   start capture group 1
    [^"]*    #     match any character other than '"' and repeat it zero or more times
    "        #     match the character '"'
    [^"]*    #     match any character other than '"' and repeat it zero or more times
    "        #     match the character '"'
  )*         #   end capture group 1 and repeat it zero or more times
  [^"]*      #   match any character other than '"' and repeat it zero or more times
  $          #   match the end of the input
)            # end positive look ahead

Другими словами: сопоставить любую запятую, которая имеет нуль, или четное число котировок впереди (до конца строки).