开发者

How can I repeat a Perl Regular Expression until no changes are left?

开发者 https://www.devze.com 2023-02-20 01:41 出处:网络
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 th

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
;
0

精彩评论

暂无评论...
验证码 换一张
取 消