Regex.Replace(myJSON, "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1")
должен это сделать. Он гарантирует, что строки, содержащие пробелы, сохраняются, а все остальные пробелы отбрасываются. Все ключевые слова JSON (false
, true
, null
) должны быть разделены запятыми или другими пунктуацией, поэтому необходимо сохранять только пробел внутри строк.
Первый параметр (\"(?:[^\"\\\\]|\\\\.)*\")
соответствует строке в двойных кавычках. Символ (...)
означает, что вывод фиксируется и доступен для замены как $1
. [^\"\\\\]
соответствует любому символу, кроме двойной кавычки или escape-символа \
.
Поскольку сопоставление происходит слева направо, второй параметр, \s+
, не будет совпадать с пробелом в строке.
Таким образом, мы сопоставляем целые строки и пробелы вне строк. В первом случае $1
является строковым токеном, а во втором случае $1
является пустой строкой, поскольку группа 1 не использовалась.
Это работает как задумано, потому что
- единственными токенами в JSON, которые могут содержать пробелы, являются строки в двойных кавычках. В JSON нет строк или комментариев в одинарных кавычках.
- грамматика JSON требует пунктуации из одного символа между всеми многосимвольными токенами, поэтому удаление пробела не объединит токены. В JavaScript это может быть проблематично, потому что для взлома токенов требуется место;
var x=0
отличается от varx=0
, а x - -(y)
отличается от x--(y)
.