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

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

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

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

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

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

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

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

Строка: {:a 3, :b 3,} <- Каждая запятая соответствует.

строка {: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

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

Другие вопросы по тегам