use strict; my $regex = qr / # start of regex ( # start of capturing alternation (?<=\') # positive lookbehind to a single quote ( # start of capture buffer 2 .*? # the value between the single quotes ) # end of capture buffer 2 (?>\') # positive lookahead to a single quote | # or (?<=\") # positive lookbehind to a double quote ( # start of capture buffer 3 .*? # the value between the double quotes ) # end of capture buffer 3 (?>\") # positive lookahead to a double quote | # or ( # start of capture buffer 4 .* # any unquoted value ) # end of capture buffer 4 ) # end of capturing alternation /x # end of regex ; &do_test (\"Now is the time"); # test with unquoted value &do_test (\"'Now is the time'"); # test with single quoted value &do_test (\'"Now is the time"'); # test with double quoted value sub do_test { print "\n"; if (${$_[0]} =~ /$regex/) { print "\$1 is $1.\n"; print "\$2 is $2.\n"; print "\$3 is $3.\n"; print "\$4 is $4.\n"; } else { print "No match.\n"; } } #### $1 is Now is the time. $2 is . $3 is . $4 is Now is the time. $1 is 'Now is the time'. $2 is . $3 is . $4 is 'Now is the time'. $1 is "Now is the time". $2 is . $3 is . $4 is "Now is the time".