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

I'm trying to split a line on double quotes. The line to be split is: type="car" of make="Ford" color="red". I wish to be able to extract, car Ford red ,from the line by splitting on the double quotes. The line: split(/"/,$line) doesn't seem to work.

Replies are listed 'Best First'.
Re: Splitting on double quotes
by BrotherAde (Pilgrim) on Aug 12, 2002 at 08:53 UTC

    First things first: the line split (/"/,$line) by itself doesn't do much. split returns a list, so you should do something like

    my @elements=split (/"/,$line)

    That gives you 'type=','car','make=' etc...

    Not what you wanted? Thought so. In order to also strip the "="-signs, you'll want to add them to the regex in the split:

    my @elements=split (/=?"/,$line)

    Added bonus: If you then do my %hash = (@elements);, you get a nice little hash:

    %hash = { type => 'car', ofmake => 'Ford', color => 'red'};

    Hope that helps,
    BrotherAde

      The hash assignment is clever, and it works in this case, but if you run under -w (and I hope you do!) and the line you are processing happens not to end with a " then there will be an odd number of elements in the elements array (the last element of the array will be the text after the last attribute), and you will get a warning Odd number of elements in hash assignment at....

      --
      mirod
      The Error Message is GOD - MJD

Re: Splitting on double quotes
by mirod (Canon) on Aug 12, 2002 at 09:01 UTC

    split will return not only the values within the quotes but also what's outside of them.

    Here I would use the fact that "attribute values" follow an = sign and do:

    #!/usr/bin/perl -w use strict; while( <DATA>) { chomp; my @atts= (m{= # an equal sign \s* # optional spaces " # a double quote ([^"]*) # capture while no double quote " # the closing double quote }gx); print "$_: ", join( "-", @atts), "\n"; } __DATA__ type="car" of make="Ford" color="red" type="car" of make="Ford" color="red" foo foo= type="car" of make="Ford" color="red" foo foo= type="car=" of make="Ford" color="red" foo
Re: Splitting on double quotes
by Ido (Hermit) on Aug 12, 2002 at 09:04 UTC
    I would use a regex instead of split:
    my($type,$make,$color)=$line=~/"([^"]*)"/g;
    Or, if you want to have quotes escaped with a backslash:
    my($type,$make,$color)=$line=~/"((?:[^"\\]*|\\"?)*)"/g;
    BTW: split(); alone can be used for the return list if assigned to @_ implicitly. The behaviour is deprecated though...
Re: Splitting on double quotes
by Abigail-II (Bishop) on Aug 12, 2002 at 11:41 UTC
    split doesn't work because split is going to split your lines, while what you want has nothing to do with splitting - you want to extract substrings delimited by double quotes.

    That's a task for Regexp::Common.

    use Regexp::Common; print "$3\n" while 'type="car" of make="Ford" color="red"' =~ /$RE{delimited}{-delim => '"'}{-keep}/g; __END__ car Ford red
    Abigail
Re: Splitting on double quotes
by dda (Friar) on Aug 12, 2002 at 08:52 UTC