Skip to content
shellhacks.dev
Regular Expressions

Match a quoted string

Match a quoted string with a negated character class. An escaped quote inside the text ends the match early, and a PCRE alternation that pairs backslashes handles it.

1 min read
Summarize in AI

Pulling the text between double quotes works until one of the strings contains an escaped quote.

Shell
line='say "hello" and "wor\"ld" end'
echo "$line" | grep -o '"[^"]*"'
echo ---
echo "$line" | grep -oP '"(?:[^"\\]|\\.)*"'
Text
"hello"
"wor\"
---
"hello"
"wor\"ld"

"[^"]*" reads an opening quote, as many non-quote characters as possible and a closing quote, so the quote after the backslash closes the second string and ld is left over. The second pattern takes either a character that is neither a quote nor a backslash, or a backslash followed by any character, which treats the escaped quote as part of the text. -P selects Perl-compatible expressions, as the GNU grep manual describes.

-P is not in POSIX grep and is missing from some builds, including the one that ships with macOS. The same pattern works as is in most languages. The match keeps the escape sequences, so unescape them afterwards. A quote that is doubled to escape itself, as in CSV, needs a different pattern, and for real CSV or JSON a parser is the better tool.

Taggedregextext
Share

More snippets

Regular Expressions

Match a UUID

Match a version 4 UUID with 8-4-4-4-12 hex groups, a 4 at the start of the third group and 8, 9, a or b at the start of the fourth. Add -i for uppercase.

2 min read
Regular Expressions

Match an ISO date

Match an ISO date with [0-9]{4}-[0-9]{2}-[0-9]{2}. The pattern checks the shape only, and a tighter month and day range still accepts February 31.

2 min read
Regular Expressions

Match a semantic version

Match a semantic version with the pattern from semver.org, which runs in grep -E. It rejects leading zeros, a bare 1.2 and a v prefix, and takes pre-release tags.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.