Janwhatever has asked for the wisdom of the Perl Monks concerning the following question:

Hi people! Need your help for what i think is a simple problem with a simple solution which i can't figure out. I have a list with phonenumbers coming from a csv file like so:

+12 34567890 +23 45678901 +34 56789012 +45 67890123 +56 78901234

And what i want is simply this:

+12 3456 7890 +23 4567 8901 +34 5678 9012 +45 6789 0123 +56 7890 1234

So basically a whitespace between the 7th and 8th character. Is it possible to do this with regex or should i think of using substr? The phonenumbers are located in column 21. I already did my research and found this topic: How do I insert (not overwrite) into a string? but i'm not sure which i should use or how i can apply this to my case. I've tried: substr ($elements[20], 0, 7) . " " . substr($elements[20], 7); This is my entire code:

if ($#ARGV != 1) {print "usage: input-file output-file \n";exit;} $inputfile=$ARGV[0]; $outputfile=$ARGV[1]; open(INFILE,$inputfile) || die "Bestand niet gevonden :$!\n"; open(OUTFILE,">$outputfile") || die "Bestand niet gevonden :$!\n"; $i = 0; @infile=<INFILE>; foreach ( @infile ) { $infile[$i] =~ s/"//g; # Verwijderd alle " per regel @elements = split(/;/,$infile[$i]); # Create array # Phonenumber clean $elements[20] =~ s/\D//g; # Clear all non-digit #print "$elements[20]\n"; $elements[20] =~ s/(^00|^0)//i; # Remove 00 and 0 #print "$elements[20]\n"; if ($elements[19] =~ m/45/g) # When 45, replace with + +45 { $elements[20] =~ s/^/\+45 /; $elements[19] =~ s/45/xxxx/; #print "$elements[20]\n"; } $elements[20] =~ s/(^450|^45)/\+45 /; # Removes 450/45 and +places +45 #print "$elements[20]"; if ($elements[20] =~ m/^[1-9]/i) # 1 to 9 gets replaced wi +th +45 { $elements[20] =~ s/^/\+45 /; #print "$elements[20]\n"; } if ($elements[20] =~ /^\+45\s{1}\d{9,}$/) { # More then 8 digit +s, nr to long $elements[25] = 'TE LANG NR'; #print "$elements[24]\n"; } if ($elements[20] =~ /^\+45\s{1}\d{1,7}$/) { # Less then 8, to +short $elements[25] = 'TE KORT NR'; #print "$elements[24]\n"; } if (!($elements[20])) { $elements[25] = 'GEEN NR BEKEND'; # Empty field = no number } if ($elements[20] =~ m/^.{12}/ substr ($elements[20], 0, 7) . " " . substr($elements[20], 7); + # End phonenumber clean @elements = join(";",@elements); # Add ';' to all elements print OUTFILE "@elements"; $i = $i+1; } close(INFILE); close(OUTFILE);

How do i fit the substr function in there? Oh fyi, i'm new to perl;)

Replies are listed 'Best First'.
Re: Add whitespace in middle of string (substr?)
by choroba (Cardinal) on Jun 12, 2012 at 09:52 UTC
    If all the numbers have the same length, substr is a good tool. Use the four-argument version to modify the string, just add a space at position 8, replacing 0 characters:
    #!/usr/bin/perl use warnings; use strict; while (my $number = <DATA>) { substr $number, 8, 0, ' '; print $number; } __DATA__ +12 34567890 +23 45678901 +34 56789012 +45 67890123 +56 78901234
Re: Add whitespace in middle of string (substr?)
by jwkrahn (Abbot) on Jun 12, 2012 at 09:56 UTC
    $ perl -le' my @numbers = ( "+12 34567890", "+23 45678901", "+34 56789012", "+45 6 +7890123", "+56 78901234" ); for my $num ( @numbers ) { print $num; substr $num, -4, 0, " "; print $num; } ' +12 34567890 +12 3456 7890 +23 45678901 +23 4567 8901 +34 56789012 +34 5678 9012 +45 67890123 +45 6789 0123 +56 78901234 +56 7890 1234
Re: Add whitespace in middle of string (substr?)
by Janwhatever (Novice) on Jun 12, 2012 at 11:44 UTC
    Hi, i've tried both your suggestions but can't seem to make it work. It gives me 2 errors:
    X:\bla\script.pl Denemarken.csv xx.csv syntax error at X:\bla\script.pl line 55, near "$elements[" syntax error at X:\bla\script.pl line 82, near "}" Execution of X:\bla\script.pl aborted due to compilation errors.
    This is my entire code:
    if ($#ARGV != 1) {print "usage: input-file output-file \n";exit;} $inputfile=$ARGV[0]; $outputfile=$ARGV[1]; open(INFILE,$inputfile) || die "Bestand niet gevonden :$!\n"; open(OUTFILE,">$outputfile") || die "Bestand niet gevonden :$!\n"; $i = 0; @infile=<INFILE>; foreach ( @infile ) { $infile[$i] =~ s/"//g; @elements = split(/;/,$infile[$i]); # Number clean if (!($elements[20] =~ /^\+45\s{1}\d{4}\s{1}\d{4}$/)) { $elements[20] =~ s/\D//g; } $elements[20] =~ s/(^00|^0)//i; if ($elements[19] =~ m/45/g) { $elements[20] =~ s/^/\+45 /; $elements[19] =~ s/45/xxxx/; } $elements[20] =~ s/(^450|^45)/\+45 /; if ($elements[20] =~ m/^[1-9]/i) { $elements[20] =~ s/^/\+45 /; } if ($elements[20] =~ /^\+45\s{1}\d{9,}$/) { $elements[25] = 'TE LANG NR'; } if ($elements[20] =~ /^\+45\s{1}\d{1,7}$/) { $elements[25] = 'TE KORT NR'; } if (!($elements[20])) { $elements[25] = 'GEEN NR BEKEND'; } while (my $elements[20] = <INFILE>) { substr $elements, 7, 0, ' '; } # Zipcode clean $elements[15] =~ s/\D//g; if (!($elements[15])) { # do nothing } else { $elements[15] =~ s/^/DK-/; } # Netnumber clean $elements[19] =~ s/\<not in use\>/xxxx/i; $elements[19] =~ s/45/xxxx/; if (!($elements[19])) { $elements[19] = 'xxxx'; } @elements = join(";",@elements); print OUTFILE "@elements"; $i = $i+1; } close(INFILE); close(OUTFILE);
    Can either of you tell me what i'm doing wrong and point me in the right direction? Because i think this is as far as my knowledge goes on the subject

      What happens when you fix those syntax errors? Perl is telling you where to find them.

      First, decide upon a sane indentation strategy and stick with it. Formatting your code consistently will aid in tracking down such mistakes as extra } braces.

      Second (your first error, actually): You can't declare a single element of an array to be lexically scoped via my. my $elements[20] is wrong.


      Dave

      The reason your attempt at substr doesn't work, this part

      while (my $elements[20] = <INFILE>) { substr $elements, 7, 0, ' '; }

      is simple, files are iterators, once you read the whole file, this part of your code  @infile=<INFILE>;

      you're at the very end, there is no more file left to read

      Also that is a syntax error

      You probably meant to write

      substr $elements[20], 7, 0, ' ';

      You ought to give perlintro another read


       if ($#ARGV != 1) {print "usage: input-file output-file \n";exit;}

      In perlish perl we write that as :)

      @ARGV or die "Usage: $0 input-file output-file\n";

      You can write it as  if( @ARGV  ){ die "Usage: $0  input-file output-file\n"; } if you're attached to if(){}

Re: Add whitespace in middle of string (substr?)
by Janwhatever (Novice) on Jun 12, 2012 at 12:50 UTC
    To be honest, i don't know perl enough to know what i did wrong yet. I know that perl is telling me where to look but i'm not seeing it. I was kinda put right in the middle of it so u can say that i've been learning it "on the fly". I have serveral books and tutorials but i have to admit i find it difficult understanding it al. So i'm still trying and will definitely give perlintro another read;) Can you show me how it's supossed to be? So i can learn from it..