Помогите с обратным ссылочным регулярным выражением в Vim - PullRequest
2 голосов
/ 23 сентября 2011

Я пытаюсь написать регулярное выражение в vi, чтобы соответствовать любому символу пробела, за которым следует любая цифра.Затем в каждом совпадении вставьте знак доллара между пробелом и цифрой.Вот пример:

A1234 12 14 B1234
B1256 A2 14 C1245
C1234 34 D1 1234K

Правильное регулярное выражение будет производить это:

A1234 $12 $14 B1234
B1256 A2 14 C1245
C1234 $34 D1 $1234K

Я понимаю, что мне нужно использовать обратную ссылку, но я не могу написатьправильное регулярное выражение.Вот моя попытка:

:'<,'>/(\s\d)/\s\1\$/g

Также у меня отключен режим регулярных выражений Vim по умолчанию (vnoremap / /\v).

Спасибо за помощь.

Ответы [ 5 ]

9 голосов
/ 23 сентября 2011

Вам нужно избегать скобок, чтобы они работали как группировки, а не как фактические совпадения в тексте, а not экранирует $.Вот так:

:%s/\(\s\)\(\d\)/\1$\2/g

Это сработало для меня в vim (используя стандартные настройки магии).

Edit : только что понял, что ваши нестандартные настройки регулярных выражений вызываютиметь побег «наоборот».Но все же, я думаю, хитрость заключается в том, чтобы использовать две группы.С вашими настройками это должно работать:

:%s/(\s)(\d)/\1$\2/g
5 голосов
/ 23 сентября 2011

Использование обратной ссылки не является неизбежным.Можно создать шаблон для сопоставления текста нулевой ширины между символом пробела и цифрой и заменить этот пустой интервал знаком $.

:'<,'>s/\s\zs\ze\d/$/g

(подробности см. :help /\zs и :help /\zeоб атомах, меняющих границы спички.)

1 голос
/ 23 сентября 2011

Моя первая мысль:

:%s/(\b\d)/$\1/g

с \b для границы слова.Но оказывается, что \b не означает границу слова в регулярном выражении Vim, а \< и \> для начала и конца слова.Таким образом, правильный ответ будет:

:%s/\(\<\d\)/$\1/g

(Обязательно избегайте скобок в захвате.)

Извините, что мое исправление пришло так поздно.

0 голосов
/ 23 сентября 2011

Это сделает работу за вас (без использования групп):

:%s/\s\@<=\d\@=/$/g

Пояснение:

  • %: на каждой строке ...
  • s: заменить ...
  • /: начало паттерна
  • \s: пробел
  • \@<=: совпадение позади (нулевая ширина)
  • \d: цифра
  • \@=: Требуется совпадение (нулевая ширина)
  • /: конец шаблона, начало замены
  • $: что вы просили!
  • /: конец замены
  • g: заменить все вхождения в строке.
0 голосов
/ 23 сентября 2011

Не уверен, точный синтаксис vim, но синтаксис regEx должен быть таким:

search expr - "(\s)([\d])"
replacement expr - "\1 $\2"

, что-то вроде:

/(\s)([\d])/\1 $\2/g
...