How can I repeat a Perl Regular Expression until no changes are left?
I'm trying to write a simple command line script to fix some whitespace and need to replace occurrences开发者_StackOverflow社区 of two spaces with a tab, but only if it appears at the beginning of the line (prefixed only by other tabs.)
I came up with s/^(\t*) /\1\t/g;
which works perfectly if I run through multiple passes, but I don't know enough about perl to know how to loop until the string didn't change, or if there is a regular expression way to handle it.
My only thought was to use a lookbehind but it can't be variable length. I'd be open to a non-regex solution if its short enough to fit into a quick command line script.
For reference, the current perl script is being executed like so:
perl -pe 's/^(\t*) /$1\t/g'
Check a very similar question.
You could use 1 while s/^(\t*) /$1\t/g;
to repeat the pattern until there are no changes left to make.
or
perl -pe 's{^(\t*)(( )+)}{$1 . "\t" x (length($2)/length($3))}e'
Supports mixes of spaces and tabs:
perl -pe'($i,$s)=/^([ \t]*)([.*])/s; $i=~s/ /\t/g; $_="$i$s";'
This is Perl, so you don't have to do a loop. Instead you could just evaluate in the replace expression, like so:
my $tl = 4;
s{ ( \t* ) ( [ ]* ) }
{ my $l=length( $2 );
"$1" . ( "\t" x int( $l / $tl )) . ( ' ' x ( $l % $tl ))
}ex
;
精彩评论