Шаблон на основе \G
обеспечивает непрерывность между совпадениями и то, что вы всегда находитесь в квадратных скобках:
gsub('(?:\\G(?!\\A)|\\[)[^]"]*\\K"', "", '["cats", "dogs"]"x"', perl=TRUE)
Или если вы хотите проверить, существует ли заключительная квадратная скобка:
gsub('(?:\\G(?!\\A)|\\[(?=[^][]*]))[^]"]*\\K"', "", '["cats", "dogs"]"x"', perl=TRUE)
Якорь \G
соответствует последней позиции, достигнутой механизмом регулярных выражений, поэтому его можно использовать для обеспечения смежности между совпадениями.
Два шаблона начинаются с чередования. Одна ветвь используется для первого совпадения (второго) и находит открывающую квадратную скобку, затем [^]"]*
достигает последнего символа, который не является кавычкой или закрывающей квадратной скобкой. \K
отмечает позицию, из которой вы хотите, чтобы символы возвращались из результата совпадения (поэтому все, что предшествует, не стирается). Другая ветвь, которая начинается с \G
, используется для следующих матчей (только сразу после предыдущего). Поскольку [^]"]*
запрещает закрывающую квадратную скобку, вы не можете выйти из квадратных скобок. Когда больше нет кавычек для замены шаблона, происходит сбой, механизм регулярных выражений переходит к следующему символу и так далее, пока вторая ветвь не преуспеет снова (если найдена открывающая квадратная скобка).
Примечание: даже если этот путьне нуждается в зависимости, имейте в виду, что это (отнюдь) менее просто для понимания, чем применение функции обратного вызова для сопоставления всего содержимого в скобках, как это делает Grothendieck.
О программедва крайних случая в моем комментарии, я думаю, что лучшее решение - сохранить кавычки, которые содержат закрывающую квадратную скобку, когда они заключены в квадратные скобки: https://regex101.com/r/SOMpqN/1