Here is my solution with test cases:
/.*?'((?:\\\\|\\'|[^'])*+)'/
And mine (Perl, but I don't use any Perl-specific functions that I don't think):
use strict; use warnings; my %tests = (); $tests{'Case 1'} = <<'EOF'; $var = 'My string'; EOF $tests{'Case 2'} = <<'EOF'; $var = 'My string has it\ challenges'; EOF $tests{'Case 3'} = <<'EOF'; $var = 'My string ends with a backslash\\'; EOF foreach my $key (sort (keys %tests)) { print "$key...\n"; if ($tests{$key} =~ m/.*?'((?:\\\\|\\'|[^'])*+)'/) { print " ... '$1'\n"; } else { print " ... NO MATCH\n"; } }
Doing this shows:
$ perl a.pl Case 1... ... 'My string' Case 2... ... 'My string has it\ challenges' Case 3... ... 'My string ends with a backslash\\'
Note that the initial template at the beginning must be non-living. Then I use matches without a backtrack to gobble up \\ and \ ', and then everything that is not a single quote character.
I think this one probably mimics the compiler's built-in approach, which should make it pretty bulletproof.
source share