Perl: Split a string on a delimiter, but respect quotes

Splitting a string on a delimiter, such as a comma or semicolon, is a common task. However, if the delimiter appears inside a quoted string, you may need to preserve it rather than split at that point. I wrote a simple function that handles this scenario and covers the majority of common use cases.

quote_split('foo, bar, baz');   # ('foo', 'bar', 'baz')
quote_split("foo, 'bar, baz'"); # ('foo', 'bar, baz')
# Split a string on commas, but respect single and double quotes with commas
sub quote_split {
    my ($str, $separator) = @_;
    $separator //= ",";
    if (!length($separator)) {
        die("quote_split separator cannot be empty\n");
    }

    my $separator_re = quotemeta($separator);
    my @items;

    while ($str =~ /\G\s*(?:
        "((?:\\.|[^"\\])*)"   # Double-quoted
        | '((?:\\.|[^'\\])*)' # Single-quoted
        | ((?:(?!$separator_re)[\s\S])+) # Unquoted
    )\s*(?:$separator_re|\z)/gcx) {

        my $item = $1 // $2 // $3;

        push(@items, $item);
    }

    return @items;
}
Tags:
All content licensed under the Creative Commons License