694 words
3 minutes
Glob and Regex Cheatsheet
There are two common pattern-matching systems: glob and regular expressions (regex). Glob is simpler and primarily used for filename matching, while regex is more expressive and used for matching, extracting, and replacing text content.
Glob (Wildcard)
Glob patterns are used for filename matching in shell commands such as ls, cp, and rm. They are simpler than regex, but still powerful for day-to-day file operations.
| Pattern/Symbol | Meaning | Example | Notes |
|---|---|---|---|
| BASIC WILDCARDS | |||
* | Matches zero or more characters | *.txt -> file.txt, a.txt | Does not match hidden files (.bashrc) |
? | Matches exactly one character | ?.txt -> a.txt, 1.txt | ab.txt will not match |
[list] | Matches any single character in list | [ab].txt -> a.txt, b.txt | c.txt will not match |
[!list] | Matches any single character NOT in list | [!a].txt -> b.txt, c.txt | a.txt will not match |
[c1-c2] | Matches any single character in range | [0-9].txt -> 0.txt to 9.txt | Follows ASCII order |
| POSIX CLASSES | Must be used inside [], e.g. [[:digit:]] | ||
[:alnum:] | Alphanumeric characters | *[[:alnum:]]* | Equivalent to [a-zA-Z0-9] |
[:alpha:] | Alphabetic characters | [[:alpha:]]*.txt | Equivalent to [a-zA-Z] |
[:digit:] | Numeric digits | log[[:digit:]].txt | Equivalent to [0-9] |
[:lower:] | Lowercase letters | [[:lower:]]*.sh | Equivalent to [a-z] |
[:upper:] | Uppercase letters | [[:upper:]]* | Equivalent to [A-Z] |
[:space:] | Whitespace characters | Useful for text processing | Space, tab, newline, etc. |
| BRACE EXPANSION | Expansion, not pattern matching | ||
{a,b,c} | Comma-separated alternatives | touch {a,b,c}.txt | Creates a.txt, b.txt, c.txt |
{1..5} | Numeric sequence | mkdir folder_{1..5} | Creates folder_1 to folder_5 |
{a..z} | Alphabetic sequence | echo {a..c} | Outputs a b c |
{,.bak} | Shorthand suffix expansion | cp config.ini{,.bak} | Same as cp config.ini config.ini.bak |
| EXTENDED GLOB (Bash) | Requires shopt -s extglob | ||
?(pattern) | Matches zero or one occurrence | file?(s).txt | Matches file.txt, files.txt |
*(pattern) | Matches zero or more occurrences | file*(s).txt | Matches file.txt, filessss.txt |
+(pattern) | Matches one or more occurrences | file+(s).txt | Matches files.txt (not file.txt) |
@(pattern) | Matches exactly one occurrence | file@(a|b).txt | Matches filea.txt, fileb.txt |
!(pattern) | Matches anything except pattern | !(*.jpg|*.png) | All files except .jpg and .png |
Quick Examples:
# Basic wildcardsls log* # All files starting with 'log'ls log? # 'log' + exactly one characterls log[123].txt # log1.txt, log2.txt, log3.txtls [!abc]* # Files NOT starting with a, b, or c
# POSIX character classesls *[[:digit:]]* # Files containing digitsls [[:lower:]]*.txt # Files starting with lowercase
# Brace expansiontouch file_{1..10}.txt # Create file_1.txt to file_10.txtcp config.ini{,.backup} # Backup config.ini
# Extended glob (enable first: shopt -s extglob)rm !(*.jpg|*.png) # Delete all except imagesls file?(s).txt # Match with optional 's'Glob Gotchas
- Hidden files:
*does not match dotfiles by default; use.*explicitly. - Path separator: Wildcards do not cross
/. Use*/*or**(withshopt -s globstar). - Shell expansion: The shell expands wildcards before passing args to commands.
- Quote protection: Quote wildcards when passing patterns as literals, e.g.
find . -name "*.txt". - Case sensitivity: Matching is case-sensitive by default; use
shopt -s nocaseglobif needed.
Regex (Regular Expression)
Regex is the “surgical knife” for text matching, extraction, and replacement. Unlike glob, regex is designed for content patterns inside strings, not filename expansion.
Regex consists of two building blocks:
- Literal characters: match themselves, e.g.
amatchesa. - Metacharacters: symbols with special meaning, e.g.
.matches almost any single character.
| Pattern/Symbol | Meaning | Example Pattern | Notes / Typical Matches |
|---|---|---|---|
| BASIC MATCHING | |||
a, cat, 2026 | Literal match | cat | Matches exact text cat |
. | Any single character except newline (usually) | b.g | bag, big, b0g |
\. | Escape metacharacter | \.com | Matches literal .com |
[abc] | Any one character in set | [bt]ag | bag, tag |
[^abc] | Any one character not in set | [^b]ag | tag, cag (not bag) |
[a-z], [0-9] | Character range | [A-F0-9] | One hex-like character |
| QUANTIFIERS | Quantifiers apply to the token immediately on the left | ||
* | 0 or more | ab* | a, ab, abbb |
+ | 1 or more | ab+ | ab, abbb (not a) |
? | 0 or 1 (optional) | colou?r | color, colour |
{n} | Exactly n | a{3} | aaa |
{n,} | At least n | a{2,} | aa, aaa, … |
{n,m} | Between n and m | a{2,4} | aa, aaa, aaaa |
*?, +?, {n,m}? | Non-greedy (lazy) quantifiers | <.*?> | Matches the shortest tag-like segment |
| ANCHORS & BOUNDARIES | Restrict where matching can happen | ||
^ | Start of line/string | ^Hello | Matches lines starting with Hello |
$ | End of line/string | done$ | Matches lines ending with done |
\b | Word boundary | \bhi\b | Matches standalone hi, not high |
\B | Not a word boundary | \Bend\B | Can match internal end in bendable |
\A, \Z | Absolute start/end (engine-dependent) | \AINFO:.*\Z | Useful when ^/$ behavior changes in multiline mode |
| PREDEFINED CLASSES | Common shorthand classes | ||
\d / \D | Digit / non-digit | \d{4} | 2026 |
\w / \W | Word char / non-word | \w+ | letters, digits, underscore |
\s / \S | Whitespace / non-whitespace | \s+ | spaces, tabs, newlines |
| GROUPING & BRANCHING | Build larger matching logic | ||
(abc) | Capturing group | (ab)+ | Repeats ab as a group |
(?:abc) | Non-capturing group | (?:cat|dog)s? | Group structure without storing capture |
(a|b|c) | Alternation (or) | cat|dog | Matches cat or dog |
\1, \2 | Backreference to captured group | (\w+)\s+\1 | Matches repeated word, e.g. go go |
| LOOKAROUNDS | Assert context without consuming characters | ||
(?=...) | Positive lookahead | \w+(?=:) | Word before : |
(?!...) | Negative lookahead | foo(?!bar) | foo not followed by bar |
(?<=...) | Positive lookbehind | (?<=\$)\d+ | Number after $ |
(?<!...) | Negative lookbehind | (?<!-)\d+ | Number not prefixed by - |
| EMPTY / BLANK MATCHING | Useful for cleanup and empty-line checks | ||
^$ | Empty line (no character at all) | ^$ | Matches truly blank lines |
^\s*$ | Blank or whitespace-only line | ^\s*$ | Matches empty lines, spaces-only, tabs-only |
^\s+|\s+$ | Leading or trailing whitespace | ^\s+|\s+$ | Common in trim replacement patterns |
Quick Examples:
- bash examples
# grep -P uses PCRE (if your grep supports -P)grep -P '^\d{4}-\d{2}-\d{2}$' dates.txt # ISO date: 2026-03-15grep -P '^\s*$' notes.txt # Empty or whitespace-only linesgrep -P '\b(error|warn|fatal)\b' app.log # Any of error/warn/fatal- javascript examples
// Extract duplicated words: "go go", "yes yes"const re = /(\w+)\s+\1/g;"go go stop".match(re); // ["go go"]
// Trim via regex replacement" hello ".replace(/^\s+|\s+$/g, ""); // "hello"Regex Gotchas
- Engine differences: JS, Python, PCRE, and Java differ in lookbehind support, Unicode behavior, and flags.
- Greedy by default:
.*consumes as much as possible; use.*?for shortest matches. - Escaping layers: Inside strings, you often need double escaping, e.g.
"\\d+". - Multiline vs singleline:
maffects^/$;sallows.to match newline. - Performance pitfalls: Nested quantifiers can cause catastrophic backtracking.
- Python tip: Prefer raw strings like
r"\d+"to avoid accidental escapes.
Glob and Regex Cheatsheet
https://yur1ka.netlify.app/posts/26_03_12_regex/ Some information may be outdated











