Как я могу повторить Perl Regular Expression, пока не останется никаких изменений? - PullRequest
5 голосов
/ 28 марта 2011

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

Я придумал s/^(\t*) /\1\t/g;, который отлично работает, если я пробегаю через несколько проходов, но я не знаю достаточно о Perl, чтобы знать, как выполнять цикл, пока строка не изменилась, или если есть способ регулярного выражения справиться с этим.

Я думал только о том, чтобы использовать вид сзади, но он не может быть переменной длины. Я был бы открыт для решения без регулярных выражений, если бы оно было достаточно коротким, чтобы вписаться в сценарий быстрой командной строки.

Для справки, текущий скрипт на Perl выполняется так:

perl -pe 's/^(\t*)  /$1\t/g'

Ответы [ 4 ]

6 голосов
/ 28 марта 2011

Отметьте очень похожий вопрос .

Вы можете использовать 1 while s/^(\t*) /$1\t/g; для повторения шаблона, пока не останется никаких изменений для внесения.

3 голосов
/ 28 марта 2011

или

perl -pe 's{^(\t*)((  )+)}{$1 . "\t" x (length($2)/length($3))}e'
1 голос
/ 28 марта 2011

Поддерживает сочетания пробелов и табуляций:

perl -pe'($i,$s)=/^([ \t]*)([.*])/s; $i=~s/  /\t/g; $_="$i$s";'
0 голосов
/ 28 марта 2011

Это Perl, поэтому вам не нужно делать цикл.Вместо этого вы можете просто выполнить оценку в выражении замены, например:

my $tl = 4;
s{ ( \t* ) ( [ ]* ) }
 { my $l=length( $2 ); 
   "$1" . ( "\t" x int( $l / $tl )) . ( ' ' x ( $l % $tl ))
 }ex
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...