How do I convert $var = "000000000"
to $var = "0_0000_0000"
in Perl ?

- 142,882
- 41
- 325
- 378

- 29
- 3
-
This question is unclear. Will your string always have 9 characters and you want the `_` after the first and fifth character? Or is there some other idea here? Please give some context. Also, usually on this site you should include some sample code of what you've already tried yourself, and we can help you as to why it isn't working. This site is not to do all of the work for you. – Andrew Jun 23 '16 at 13:19
-
$var=000000000 next line: substr($var, 1, 0) = '\_' next line substr($var, 6, 0) = '\_' – Destrif Jun 23 '16 at 13:21
-
Yes, the string will always be of 9 characters and the position of _ should be after the 1st and 5th character – SID Jun 23 '16 at 13:21
-
for example: `$var =~ s/^(.)(.{4})/$1_$2_/;` – clt60 Jun 23 '16 at 13:26
5 Answers
If the string is always 9 characters long, you can just use substr
:
my $var = '000000000';
substr($var, 5, 0) = '_';
substr($var, 1, 0) = '_';
For formatting strings of arbitrary length you could use a function like this:
sub format_str {
my $str = reverse $_[0];
$str =~ s/(.{4})(?=.)/$1_/g;
return scalar reverse $str;
}
my $var = "000000000";
print format_str $var; # "0_0000_0000"

- 142,882
- 41
- 325
- 378
$var = "000000000";
$var2 = substr($var,0,1)."_".substr($var,1,4)."_".substr($var,5);
print $var2;

- 368
- 1
- 8
For a solution for any-length string and considering efficiency issues that arise for very-long strings, please see my previous question&answer: How to chunk text "from the back" in perl.
Per suggestion in comment, here is code using the idea in the linked question/answer which answers the OP question:
use integer;
my $la = length($var);
my $r = $la % 4;
my $q = $la / 4;
my $tr = $r ? "a$r" : "";
$var = join "_", unpack "$tr(a4)$q", $var;
Note: change all three 4
s for a different grouping size.
Assuming you're asking how to insert a _
after the first and fifth characters of a string, the following are a variety of straightforward solutions:
my $in = '000000000';
my $out = substr($var,0,1) . '_' . substr($var,1,4) . '_' . substr($var,5);
my $in = '000000000';
my $out = join('_', substr($var,0,1), substr($var,1,4), substr($var,5));
my $in = '000000000';
my $out = join('_', unpack('a1 a4 a4*', $in));
my $in = '000000000';
my $out = $in =~ s/^(.)(.{4})/${1}_${2}_/sr; # 5.14+
my $in = '000000000';
( my $out = $in ) =~ s/^(.)(.{4})/${1}_${2}_/s;
In-place:
my $var = '000000000';
$var =~ s/^(.)(.{4})/${1}_${2}_/s;
my $var = '000000000';
substr($var, 5, 0) = '_';
substr($var, 1, 0) = '_';

- 367,544
- 15
- 269
- 518
If this is a commify problem that is solved in "How can I output my numbers with commas added?", available as perldoc -q 'commas added'
, then a similar solution will suffice, with extra parameters to define the separator and the size of the interval
You will want to read the perlfaq
entry for other alternatives
use strict;
use warnings 'all';
print group_characters(1234567), "\n";
print group_characters('000000000', '_', 4), "\n";
print group_characters('0123456789ABCDEF', ' ', 4), "\n";
sub group_characters {
my ($s, $sep, $n) = @_;
$sep //= ',';
$n //= 3;
1 while $s =~ s/[^$sep]+\K(?=[^$sep]{$n})/$sep/;
$s;
}
output
1,234,567
0_0000_0000
0123 4567 89AB CDEF

- 126,100
- 9
- 70
- 144