himanshu.padmanabhi has asked for the wisdom of the Perl Monks concerning the following question:

Inputs can either be
A) 1:2 B) -p 1 -t 2 3 C) 1 2 .....in this fashion...Yes they are arguments to program
I corresponding want outputs to be
A) args1:args2 B) -p args1 -t args2 args3 C) args1 args2 ...like this.
Basically want to replace 1 by args1,2 by args2..so on,keeping space,colon,dash like things in input the same.

Replies are listed 'Best First'.
Re: replace number by args<number>
by wfsp (Abbot) on Mar 20, 2009 at 08:32 UTC
    It might be worth having another look at regular expressions’s as I notice you are familiar with them. You posted some code with that question and you got some good help and advice.

    Have a stab at the problem yourself and let us know how you get on. If you get stuck we’ll see if we can help.

    Good luck!

Re: replace number by args<number>
by johngg (Canon) on Mar 20, 2009 at 12:37 UTC

    An alternative to using a regular expression with a capture of a digit and subsequent replacment with args$1 would be to use a zero-width look-ahead, effectively inserting "args" at any point followed by a digit.

    use strict; use warnings; my @inputs = ( q{A) 1:2}, q{B) -p 1 -t 2 3}, q{C) 1 2}, q{D) 12}, ); my @outputs = map { s{(?=\d)}{args}g; $_ } @inputs; print qq{$_\n} for @outputs;

    The output.

    A) args1:args2 B) -p args1 -t args2 args3 C) args1 args2 D) args1args2

    I hope this is useful.

    Cheers,

    JohnGG

Re: replace number by args<number>
by AnomalousMonk (Archbishop) on Mar 20, 2009 at 11:57 UTC
    Try something like:
    >perl -wMstrict -le "for my $string (@ARGV) { (my $arged = $string) =~ s{ (\d) }{arg$1}xmsg; print qq{'$string' yields '$arged'}; } " "1:2" "-p 1 -t 2 3" "1 2" "12" "no digits" '1:2' yields 'arg1:arg2' '-p 1 -t 2 3' yields '-p arg1 -t arg2 arg3' '1 2' yields 'arg1 arg2' '12' yields 'arg1arg2' 'no digits' yields 'no digits'
    Update: Extended tests to include "no digits" case.
Re: replace number by args<number>
by JavaFan (Canon) on Mar 20, 2009 at 09:53 UTC
      Without using regular expression,Following already gave me what I want.I just wanted to make it better using regular expression,but I couldn't think of any..:(
      $ret=index($in{'cmd'},":"); if($ret eq -1) { @arr=split(/ /,$in{'cmd'}); $delim=" "; } else { @arr=split(/:/,$in{'cmd'}); $delim=":"; } $i=0; while(@arr[$i]) { if(@arr[$i] == 1) { $cmd=$cmd.$in{'args1'}.$delim; }elsif(@arr[$i] == 2) { $cmd=$cmd.$in{'args2'}.$delim; }elsif(@arr[$i] == 3) { $cmd=$cmd.$in{'args3'}.$delim; }else { $cmd=$cmd.@arr[$i].$delim; } $i++; } chop($cmd);
      12
      should become
      args1args2
Re: replace number by args<number>
by VinsWorldcom (Prior) on Mar 20, 2009 at 11:50 UTC

    Try MSAR.

    In file:

    1:2 -p 1 -t 2 3 1 2

    Map file:

    1 arg1 2 arg2 3 arg3

    Output:

    {C} > msar in.txt map.txt Reading mappings from file: map.txt ---------------------------- arg1:arg2 -p arg1 -t arg2 arg3 arg1 arg2 ---------------------------- Mapped 7 entries.

    You can review the coding in MSAR.pl, but I think you'll be interested in the regex:

    ($_ =~ s/$replace/$map{$replace}/gi)
Re: replace number by args<number>
by rovf (Priest) on Mar 20, 2009 at 12:03 UTC

    Not tested, but it should give you the idea:

    join('',(map { /\d/ ? "args$_" : $_ } split(/(\d+)/,$yourInputGoesHere +)))
    Maybe someone could suggest how to write the map block in a nicer way? It looks a bit clumsy.

    -- 
    Ronald Fischer <ynnor@mm.st>
      Maybe someone could suggest how to write the map block in a nicer way? It looks a bit clumsy.
      I agree it looks clumsy. But, IMO, the clumsy part is using split, map and join. Why?
      $yourInputGoesHere =~ s/([0-9])/args$1/g;
      No split. No map. No join. Nothing clumsy here.

        Oh my god! I didn't see the obvious :-O

        -- 
        Ronald Fischer <ynnor@mm.st>
      >perl -wMstrict -le "printf qq{'%s' yields '%s' \n}, $_, join '', map /\d/ ? qq{arg$_} : $_, split /(\d+)/ for @ARGV ; " "1:2" "-p 1 -t 2 3" "1 2" "12" "no digits" '1:2' yields 'arg1:arg2' '-p 1 -t 2 3' yields '-p arg1 -t arg2 arg3' '1 2' yields 'arg1 arg2' '12' yields 'arg12' 'no digits' yields 'no digits'
      Note that  split /(\d+)/ does not give the OPer's specified 'arg1arg2' from '12', for which  split /(\d)/ vice  split /(\d+)/. (However, I still prefer the  s///g approach.)