Basic Regular Expressions in Bash ([[ =~ ]])
In this page:
Basic Pattern Matching
The =~ operator inside [[ ]] tests whether the left-hand string matches the extended regular expression on the right. The exit status of the [[ ]] reflects whether the match succeeded.
Example: Basic Pattern Matching
#!/bin/bash
value="hello123"
if [[ $value =~ [0-9]+ ]]; then
echo "contains digits"
fi
Login to try C/C++/Java/PHP code in the editor
Capturing Groups with BASH_REMATCH
When a regex includes parenthesized groups, a successful =~ match populates the BASH_REMATCH array: index 0 is the whole match, and indices 1+ correspond to each capture group in order.
Example: Capturing Groups with BASH_REMATCH
#!/bin/bash
version="v2.5.1"
if [[ $version =~ v([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
echo "major: ${BASH_REMATCH[1]}"
echo "minor: ${BASH_REMATCH[2]}"
echo "patch: ${BASH_REMATCH[3]}"
fi
Login to try C/C++/Java/PHP code in the editor
Storing a Pattern in a Variable
Keeping the regex in a variable and using it unquoted in the [[ ]] test avoids accidental literal-string matching and makes complex patterns easier to read and reuse.
Warning: Quoting the pattern (e.g. [[ $email =~ "$pattern" ]]) turns it into a literal string match in bash, silently breaking the regex.
Example: Storing a Pattern in a Variable
#!/bin/bash
email="[email protected]"
pattern='^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'
if [[ $email =~ $pattern ]]; then
echo "looks like a valid email format"
else
echo "does not look like an email"
fi
Login to try C/C++/Java/PHP code in the editor
Validating Input Format
Regex matching with =~ is commonly used to validate that input has an expected shape, such as being all digits, before proceeding with further processing.
Example: Validating Input Format
#!/bin/bash
check_number() {
if [[ $1 =~ ^[0-9]+$ ]]; then
echo "$1 is a valid whole number"
else
echo "$1 is NOT a valid whole number"
fi
}
check_number "12345"
check_number "12a45"
Login to try C/C++/Java/PHP code in the editor
- Quoting the regex on the right side of
=~; quoting it forces a literal string match in some bash versions instead of treating it as a pattern. - Confusing
=~regex syntax (POSIX extended regex) with glob syntax used incaseor filename matching; they use different metacharacters. - Forgetting that
BASH_REMATCHholds the whole match at index 0 and capture groups starting at index 1, only immediately after a successful=~test.
[[ $string =~ $pattern ]]tests a string against a POSIX extended regular expression.- Leave the pattern unquoted (or store it in a variable) so bash treats it as a regex, not a literal string.
BASH_REMATCH[0]holds the full match;BASH_REMATCH[1],[2], etc. hold capture groups.=~is bash-specific and not available in POSIXshor[ ](single-bracket) tests.
Chapter Quiz — Complete all 12 topics to unlock
0/12 topics done
Complete these topics first: