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

I am trying to take a long string such as
jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"jkl45;fs ier987543" fsdjkal"
and split it into an array -- everything before the 1st double (or single) quotation mark into the 1st element, everything from there to the 2nd double (or single) quotation mark into the 2nd element, everything from there to the 3rd quotation mark into the 3rd element, and so on.
In the end, the string would be split like so:
jfjsa as,.n d
"fdsafjl"
jop
'fdsjklf fds'
457
"fjdsklaoir"
jkl45;fs ier987543
" fsdjkal"
Thanks in advance!
  • Comment on Split into array in a somewhat unconventional manner

Replies are listed 'Best First'.
Re: Split into array in a somewhat unconventional manner
by ikegami (Patriarch) on Aug 18, 2009 at 19:54 UTC
    use strict; use warnings; use Text::Balanced qw( gen_delimited_pat extract_multiple ); my $text = q{jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"jkl4 +5;fs ier987543" fsdjkal"}; my @extracted = extract_multiple($text, [ gen_delimited_pat(q{'"}), ]); print "$_\n" for @extracted;
    jfjsa as,.n d "fdsafjl" jop 'fdsjklf fds' 457 "fjdsklaoir" jkl45;fs ier987543 " fsdjkal"

    Text::Balanced

    Update: The difference between mine and OGB's is that mine allows escaped delimiters such as 'foo\'s room' and mine doesn't strip the delimiters as per your requested output.

Re: Split into array in a somewhat unconventional manner
by Old_Gray_Bear (Bishop) on Aug 18, 2009 at 19:59 UTC
    I believe that
    split(/"|'/,<your funny string goes here)
    will do what you want. Here, let's test that supposition:
    #! /usr/local/bin/perl use strict; use warnings; my $str =qq(jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"jkl45 +;fs ier987543" fsdjkal"); my @arr = split(/'|"/,$str); print("Number of bits: ", scalar(@arr),"\n"); print("Resultant array: " , join(' ', @arr), "\n"); exit(0)
    prints
    Resultant array: jfjsa as,.n d fdsafjl jop fdsjklf fds 457 fjdskl +aoir jkl45;fs ier987543 fsdjkal

    ----
    I Go Back to Sleep, Now.

    OGB

      I don't think that your code does quite what the OP wanted. The contents of the wanted array as posted indicate that the single- and double-quotes should be preserved around the text they are quoting. This could be achieved using a capture in the regex used to split the string.

      #!/usr/bin/perl -l # use strict; use warnings; my $str = q{jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"jkl45;fs ier +987543" fsdjkal"}; my $rxSplit = qr {(?x) # Use extended syntax ( # Open capture group (?: # Open group for alternation of "[^"']*" # "whatever" | # or '[^"']*' # 'some other thing' ) # Close alternation group ) # Close capture group }; my @arr = split m{$rxSplit}, $str; print for @arr;

      The output.

      jfjsa as,.n d "fdsafjl" jop 'fdsjklf fds' 457 "fjdsklaoir" jkl45;fs ier987543 " fsdjkal"

      I hope this is of interest.

      Cheers,

      JohnGG

        That creates empty elements if you have two delimited strings in a row. split really isn't the right tool.
Re: Split into array in a somewhat unconventional manner
by jwkrahn (Abbot) on Aug 18, 2009 at 21:14 UTC
    $ perl -le' $x = qq[jfjsa as,.n d"fdsafjl"jop\047fdsjklf fds\047457"fjdsklaoir"jkl +45;fs ier987543" fsdjkal"]; print $x; @x = $x =~ /"[^"]*"|\047[^\047]*\047|[^"\047]*/g; print for @x; ' jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"jkl45;fs ier98754 +3" fsdjkal" jfjsa as,.n d "fdsafjl" jop 'fdsjklf fds' 457 "fjdsklaoir" jkl45;fs ier987543 " fsdjkal"
Re: Split into array in a somewhat unconventional manner
by bichonfrise74 (Vicar) on Aug 19, 2009 at 01:29 UTC
    I think a simple split function will do the trick for you...
    #!/usr/bin/perl use strict; my $string = qq{jfjsa as,.n d"fdsafjl"jop'fdsjklf fds'457"fjdsklaoir"j +kl45;fs ier987543" fsdjkal"}; my @arrays = split( "\"|\'", $string ); print join "\n", @arrays;
Re: Split into array in a somewhat unconventional manner
by Anonymous Monk on Aug 18, 2009 at 22:24 UTC
    Thanks everyone!