#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11137926 use warnings; use Data::Dump 'dd'; my @tests = ( # q{all '- and "-quotes properly balanced}, [ q{This is simple.}, [ q{This}, q{is}, q{simple.} ] ], [ q{ This is simple. }, [ q{This}, q{is}, q{simple.} ] ], [ q{This is "so very simple".}, [ q{This}, q{is}, q{"so very simple".} ] ], [ q{This "is so" very simple.}, [ q{This}, q{"is so"}, q{very}, q{simple.} ] ], [ q{This 'isn\'t nice.'}, [ q{This}, q{'isn\'t nice.'} ] ], [ q{This "isn\"t nice."}, [ q{This}, q{"isn\"t nice."} ] ], [ q{This 'isn\\\\'t nice.'}, [ q{This}, q{'isn\\\\'t}, q{nice.'} ] ], [ q{This "isn\\\\"t nice."}, [ q{This}, q{"isn\\\\"t}, q{nice."} ] ], [ q{This 'is not unnice.'}, [ q{This}, q{'is not unnice.'} ] ], [ q{This "is not unnice."}, [ q{This}, q{"is not unnice."} ] ], [ q{a "bb cc" d}, [ q{a}, q{"bb cc"}, q{d} ] ], # q{UNbalanced '- and "-quotes at absolute end of string}, [ q{This is "so very simple}, [ q{This}, q{is}, q{"so very simple} ] ], [ q{This 'isn\'t nice.}, [ q{This}, q{'isn\'t nice.} ] ], [ q{This "isn\"t nice.}, [ q{This}, q{"isn\"t nice.} ] ], [ q{This 'isn\\\\'t nice.}, [ q{This}, q{'isn\\\\'t}, q{nice.} ] ], [ q{This "isn\\\\"t nice.}, [ q{This}, q{"isn\\\\"t}, q{nice.} ] ], [ q{This 'is not unnice.}, [ q{This}, q{'is not unnice.} ] ], [ q{This "is not unnice.}, [ q{This}, q{"is not unnice.} ] ], # 'what about these questionable cases?', [ q{is this"really so"simple now?}, [ q{is}, q{this"really so"simple}, q{now?} ] ], [ q{is this"really so" now?}, [ q{is}, q{this"really so"}, q{now?} ] ], [ q{is "really so"simple now?}, [ q{is}, q{"really so"simple}, q{now?} ] ], [ q{is this'really so'simple now?}, [ q{is}, q{this'really so'simple}, q{now?} ] ], [ q{is this'really so' now?}, [ q{is}, q{this'really so'}, q{now?} ] ], [ q{is 'really so'simple now?}, [ q{is}, q{'really so'simple}, q{now?} ] ], [ q{is really\\ so\\ simple now?}, [ q{is}, q{really\\ so\\ simple}, q{now?} ] ], ); my $regex = qr/(?: '(?: \\. | [^'\\] )*' # single quoted string | "(?: \\. | [^"\\] )*" # double quoted string | ['"].* # unmatched quote | \\. # escaped character | \S # single non-space character )+/x; my $passcount = 0; for ( @tests ) { my ( $string, $want ) = @$_; my @out = $string =~ /$regex/g; local $" = "\0"x5; # just some array element boundary separator "@$want" eq "@out" ? $passcount++ : dd "$string => FAILED got", \@out, ' wanted ', $want; } print "$passcount of @{[scalar @tests]} passed\n"; #### 25 of 25 passed