У меня есть текст в follwing формате:
ERR_OUT_OF_MEM, "ERR OUT OF MEM"
ERR_SOMETHING_BAD, "ERR SOMETHING BAD"
Я хочу заменить все пробелы в тексте, которые являются в кавычках с символами нижнего подчеркивания:
ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM"
ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD"
Лучший regex, который я мог придумать:
\("\w\+\)\@<=
(существует пространство в конце этого),
но это только находит первое пространство в каждой заключенной в кавычки строке, и я должен был бы повторить это многократно для получения желаемого эффекта.
Какой-либо способ сделать это в одном выстреле?
Спасибо!
Конечно, существует шаблон длины 0, который работает за один проход, но поскольку я никогда не добивался большого успеха, используя их, я предпочитаю такой подход:
:%s/\%("[^"]*"\)*\("[^"]*"\)/\=substitute(submatch(1), ' ', '_', 'g')/g
Примечание: двойные кавычки сгруппированы по 2, чтобы не превращать
foo bar "foo bar" "foo barr"
в
foo bar "foo_bar"_"foo_barr"
EDIT: как отметил rampion, следующего более чем достаточно:
%s/"[^"]*"/\=substitute(submatch(0), ' ', '_', 'g')/g
Это решение не общего назначения, поскольку оно будет соответствовать любому пробелу, которое появляется в любом месте после двойной кавычки в строке, но оно должно работать для строк в указанном вами формате:
s/\v(\".*)@<= /_/g
Я использовал токен \ v (verymagic), потому что я думаю, что он делает регулярное выражение немного более читаемым, и я включил всю команду подстановки, так как 'g' в конце важен.
Для тех, кто следит за происходящим дома, это регулярное выражение сначала устанавливает режим «verymagic» с помощью \ v. Затем он определяет токен (\ ". *)
, который примерно означает« двойные кавычки, а затем что-нибудь еще », и использует утверждение lookbehind @ <=
, чтобы сказать« соответствовать только следующим этот последний токен "- другими словами, сопоставлять только те вещи, которые идут где-то после двойных кавычек. Наконец, есть пробел, который фактически соответствует, и термин подстановки - это подчеркивание, которое мы хотим заменить на , а g
говорит «заменить все совпадающие термины», чтобы мы не получали только первое найденное совпадение.