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

hi, i have this string :
"2","T,E,S,T,B","Lazowsky","Mike's","Teststring"

I need to remove all commas from within "T,E,S,T,B" but leave all the other commas intact...i'd appreciate any help you can give me on this issue.
Thanks.

Replies are listed 'Best First'.
(jeffa) Re: finding commas within commas
by jeffa (Bishop) on Jan 24, 2003 at 01:28 UTC
    use Text::CSV
    use strict; use warnings; use Text::CSV; my $str = q|"2","T,E,S,T,B","Lazowsky","Mike's","Teststring"|; my $csv = Text::CSV->new(); $csv->parse($str); my @field = $csv->fields(); s/,//g for @field; $csv->combine(@field); print $csv->string(),$/;

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: finding commas within commas
by sauoq (Abbot) on Jan 24, 2003 at 01:27 UTC

    The Right Way™ to do this is to use Text::CSV to split your data, remove commas from any field you want to, then re-join your data.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: finding commas within commas
by BrowserUk (Patriarch) on Jan 24, 2003 at 01:34 UTC

    All that can be said for this solution is that it works on your test string. Beyond that?

    my $str = q["2","T,E,S,T,B","Lazowsky","Mike's","Teststring"]; $str =~ s< \s* ( \"[^\"]+ \" \s* ) (,|$) > < (local $a = $1) =~ tr/,//d; $a . $2 ; >gex; #!" print $str; __END__ #Output C:\test>229505 "2","TESTB","Lazowsky","Mike's","Teststring" C:\test>

    Update: Corrected error that LAI++ spotted.

    That said, Text::CSV is almost certainly better.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

      Actually, this breaks if there are commas in the last field. Since you're checking for commas at the end of the field a string like q["2","T,E,S,T,B","Lazowsky","Mike's","Test,string"] will not have the comma in "Test,string" removed.

      Update: BrowserUk++ fixed this. And yes, Text::CSV is a good idea.


      LAI
      :eof
      thanks, that seemed to work for me. I was wondering if you could elaborate on how that code works...i'm not too clear on how the code works exactly...
      thanks once again

        Sure. Essentially, this is just a s/// operator. I've used angle brackets instead of slashes as the delimiter.

        $str =~ s< ( # Start capturing (to $1) \s* # Optional whitespace (forgot this before) \" # starting with a quote [^\"]+ # 1 more of anything except a quote \" # another quote \s* # optional white space ) # end capture (,|$) # capture comma seperator (or EOL*) > < # /e option makes this becomes a code block # put the contents of $1 into a localised writable var #($1 is read only!) # and use the tr/// op to remove the commas (local $a = $1) =~ tr/,//d; # The last expression in the block is used as the # replacement expression, so we put the decomma'd localise +d var here. # not forgetting to put back the final comma # If it was there* $a .$2 ; >gex; #!" Global, Execute, ignore whitespace in regex

        The weird comment (#!") I forgot to remove, is just used to keep the syntax parser in my editor happy. Sorry for any confusion it caused.

        Update* Added to correct error spotted by LAI. Use Text::CSV instead.


        Examine what is said, not who speaks.

        The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: finding commas within commas
by Wonko the sane (Curate) on Jan 24, 2003 at 03:29 UTC
    How about this for a different way to do it.
    #!/usr/local/bin/perl -w use strict; my $string = q{"2","T,E,S,T,B","Lazowsky","Mike's","Teststring"}; $string =~ s/,(?!")//g; print qq{[$string]\n};
    Outputs: ["2","TESTB","Lazowsky","Mike's","Teststring"]

    Uses Negative Lookahead Assertion.
    Essentially, this is saying, to remove any commas, as long as they are not followed by a double quote.

    Warning: definitely not production code, there are several problems with this.
    Text::CSV, is the way to go.

    Best Regards,
    Wonko

Re: finding commas within commas (Text::xSV)
by tye (Sage) on Jan 24, 2003 at 15:45 UTC

    And if you want to be able to have newlines inside of your strings, then you'll want Text::xSV instead of Text::CSV.

                    - tye
Re: finding commas within commas
by OM_Zen (Scribe) on Jan 26, 2003 at 14:30 UTC
    Hi ,

    my $string = q{"2","T,E,S,T,B","Lazowsky","Mike's","Teststring"}; $string =~ s< (,[A-Z]) > < (local $a = $1) =~ tr/,//d; $a >gex;


    This also works for the $string and gives the TESTB without commas