[[:alpha:]] — POSIX bracket classes, which four engines have and four read as garbage¶
One line: [[:digit:]], [[:alpha:]], [[:space:]] and the rest are the POSIX spelling of character categories; Perl, Ruby, Go and Rust accept them (Perl and Ruby with Unicode meaning, Go and Rust ASCII-only), and Python, JavaScript and Java compile the same text as a class containing the characters [, :, d, i, g, t — with no error.
Level: reference · one construct, eight engines
What it means¶
The syntax comes from POSIX regex(7), which is what grep, sed, awk and C's <regex.h> implement. The double brackets are not a typo: [:digit:] is the class name, and it is only valid inside an outer [...], so it can be combined — [[:alpha:]_] is letters or underscore.
| Engine | [[:name:]] |
Meaning |
|---|---|---|
| Perl, PCRE2 (so ABAP) | yes | Unicode-aware on decoded text; [[:^name:]] negates |
| Ruby | yes | Unicode-aware |
Go regexp, Rust regex |
yes | ASCII only — RE2's documented rule |
POSIX grep/sed/awk, C |
yes | locale-dependent |
Python re, JavaScript, Java |
no — silently a class of six characters | — |
Java's alternative is \p{Alpha} and friends, which are ASCII by default; Python and JavaScript have no equivalent and use \p{…} (JavaScript with u) or \w-style shorthands.
Measured¶
Verified output of kw_posix_classes_sh.sh — regenerated by tools/run_examples.py, never hand-typed.
construct python perl node ruby java go rust fancy
[[:digit:]] no 12 no 12 no 12 12 12
[[:alpha:]] on Greek no \u{3B1}b no \u{3B1}b no b b b
[[:word:]] on Latin-1 no \u{E9}a no \u{E9}a no a a a
[[:^digit:]] negation no ab no ab no ab ab ab
\p{Alpha} on Greek - \u{3B1}b no \u{3B1}b b - \u{3B1}b \u{3B1}b
outside brackets : : : : : : : :
Reading the table¶
- Row 1,
[[:digit:]]+ona12. Perl, Ruby, Go, Rust andfancy-regexreturn12. Python, JavaScript and Java returnno— not a refusal. They parsed[[:digit:]]as the class[[:digt]followed by a literal], anda12contains none of those characters. Python prints aFutureWarningabout a "possible nested set" on stderr; JavaScript and Java say nothing at all. - Rows 2–3, on
αbandéa. Perl and Ruby take the whole word — POSIX classes there are Unicode-aware. Go and Rust returnbanda: the classes are ASCII by definition in RE2 syntax, and the match starts at the first ASCII letter. This is the row that makes "does it support POSIX classes" two questions rather than one. - Row 4,
[[:^digit:]]. The negated form, a Perl invention that Ruby, Go and Rust also accept. - Row 5,
\p{Alpha}. The Java spelling — and in Java it means ASCII (b), while in Perl, Ruby and Rust it means Unicode (αb). Python refuses\pentirely; Go refuses this name (it knows categories and scripts, not POSIX names); JavaScript withoutureads it as the lettersp{Alpha}. - Row 6,
[:digit:]+with one pair of brackets. All eight matched the colon, because outside an enclosing class the text is an ordinary set of the characters:,d,i,gandt. Perl warns about it. The others do not.
The trap¶
A pattern copied from a shell script into Python. grep -E '[[:space:]]+' is correct and idiomatic; the same string handed to re.compile is a class of five characters, and a test that happens to contain a colon or a t will pass. Translate to \s+ — and then check which \s you now have, per shorthand classes.
Where it is measured in depth¶
- Naming a Unicode property — the
\p{Alpha}collision in Java, and what\p{…}offers instead. - Two definitions of "the match" — the POSIX engines these classes come from.
See also¶
- Character class · Shorthand classes ·
\p{…}. - Command-line tools — where
[[:alpha:]]is the native spelling.