VIM 7.2 Сценарий проблемы с `: perldo` и несколькими выражениями - PullRequest
7 голосов
/ 01 февраля 2010

Фоновое задание

Чтобы устранить проблемы X-Y, я скажу, что я делаю: я пытаюсь использовать :perldo в VIM 7.2 для выполнения двух задач:

  • Очистить все конечные пробелы, включая (очистка, но не удаление) строки, которые только имеют пробелы
    • s/\s+$//;
  • Удалите пробелы без табуляции, которые существуют перед первым непробельным символом
    • s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;

Я бы хотел сделать все это за один проход. В настоящее время, используя :perldo, я могу заставить это работать с двумя проходами. (используя: perldo дважды)

Команда должна выглядеть так:

:perldo s/\s+$//; s/^ (\s*) (?=\S) / s#[^\t]##g;$_ /xe;

фон Perl

Чтобы понять эту проблему, вы должны немного знать о Perl s///, автоматически связывающем переменную по умолчанию $_, которую регулярное выражение может свободно изменять. Большинство основных функций по умолчанию работают на $_.

perl -e'$_="foo"; s/foo/bar/; s/bar/baz/; print' # напечатает baz

Предполагается, что вы можете связывать выражения, используя :perldo в VIM, и это будет работать логически.

VIM нехорошо

Теперь моя проблема с VIM лучше демонстрируется с помощью кода - я сократил ее до простого теста. Откройте новый буфер и поместите в него следующий текст:

aa bb
aa
bb

Теперь запустите это :perldo s/a/z/; s/b/z/; В буфере теперь есть:

za zb
aa
zb

Почему первое регулярное выражение оказалось неудачным во втором ряду, и все же второе регулярное выражение было успешным само по себе и в первом ряду?

Ответы [ 3 ]

6 голосов
/ 02 февраля 2010

Похоже, что все выражение Perl, которое вы передаете :perldo, должно возвращать истинное / определенное значение, или результаты отбрасываются для каждой строки.

Попробуйте, ничего не происходит ни в одной строке:

:perldo s/a/z/; s/b/z/; 0

Попробуйте, это работает на все 3 строки, как и ожидалось:

:perldo s/a/z/; s/b/z; 1

Пример из документации :perldo намекает на это:

:perldo $_ = reverse($_);1

но, к сожалению, он не говорит явно, что происходит.

5 голосов
/ 01 февраля 2010

Не знаю, что точно делает :perldo, но если вы запустите что-то вроде

:perldo s/a/z/+s/b/z/

тогда вы получите нечто большее, чем ожидаете.

0 голосов
/ 01 февраля 2010

Мне кажется, что только последняя команда запускается во всех строках в [range].

...