Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Adding Leading Zeroes With a Single Substitution Without /e Option

Status
Not open for further replies.

WingedKnight

Programmer
Apr 21, 2010
11
US
Suppose you have an integer $n and you want to add enough leading zeroes to that integer to make it a certain width in characters (for the examples below, let's say a width of 5.) I'm well aware that this can be done with such ways as

Code:
$n = sprintf("%05d", $n);

$n = substr(0 x 5 . "$n", -5);

The above statements can be converted into regex form:

Code:
$n =~ s/(\d+)/sprintf("%05d", $1)/e;

$n =~ s/(\d+)/substr(0 x 5 . "$1", -5)/e;

Is there any way to add leading zeroes with a single-line regex substitution without using the "/e" option?
 
You might be able to do something fancy with look-ahead and/or look-behind, but I couldn't figure that out. I couldn't get it to work with a /g global match either, but a while loop does the trick. Is that cheating?

Code:
while ($n =~ s/(^|\D)(\d{1,4}(\D|$))/${1}0${2}/) { }

There's probably a neater alternative to my home-made anchors either side of the number too...

Annihilannic.
 
That's clever, Annihilannic, and I thank you for your efforts, but unfortunately, it doesn't solve my problem.

This isn't just a theoretical question. There is a program which has an interface that allows the user to set a single regex substitution in the middle of a much larger, more complex calculation. Unfortunately, that regex substitution is one without the /e option being set. That single regex substitution needs to format its input to insert the appropriate number of leading zeroes.

I do not have access to the program source and cannot modify the program. Nor can I modify the input that goes into that regex substitution step other than with that single regex substitution itself.

That's why I need some single regex substitution, without the /e option, that will add the appropriate number of leading zeroes.
 
Letting the users enter a regex probably isn't the safest thing.

Code:
my $n = 12;
$n =~ s/(\d+)(?{ $_ = sprintf("%05d", $^N) })/$_/;
print $n;

It's still possible to run arbitrary code without the 'e' modifier.
 
rharsh's solution unfortunately doesn't work either, as like the "/e" option it involves the evaluation of arbitrary code (it gets kicked with the error message "Eval-group not allowed at runtime").
 
Well, the other thing I tried was this zero-width look-ahead:

Code:
my $n='2ab54cd3fg hi 293 j 123456 7';

print "$n\n\n";

($r = $n) =~ s/(?=\d{1,4}(\D|$))/0/g;
print "$r\n";

Code:
2ab54cd3fg hi 293 j 123456 7

02ab0504cd03fg hi 020903 j 1203040506 07

Unfortunately it seems that with each iteration of the global replace it is advancing a character further into the search string... not sure why?


Annihilannic.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top