Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does \w match all alphanumeric characters defined in the Unicode standard?

Tags:

Does Perl's \w match all alphanumeric characters defined in the Unicode standard?

For example, will \w match all (say) Chinese and Russian alphanumeric characters?

I wrote a simple test script (see below) which suggests that \w does indeed match "as expected" for the non-ASCII alphanumeric characters I tested. But the testing is obviously far from exhaustive.

#!/usr/bin/perl                                                                                                                                                                                                  

use utf8;

binmode(STDOUT, ':utf8');

my @ok;
$ok[0] = "abcdefghijklmnopqrstuvwxyz";
$ok[1] = "éèëáàåäöčśžłíżńęøáýąóæšćôı";
$ok[2] = "şźüęłâi̇ółńśłŕíáυσνχατςęςη";
$ok[3] = "τσιαιγολοχβςανنيرحبالтераб";
$ok[4] = "иневоаслкłјиневоцедањеволс";
$ok[5] = "рглсывызтоμςόκιναςόγο";

foreach my $ok (@ok) {
    die unless ($ok =~ /^\w+$/);
}
like image 286
knorv Avatar asked Apr 05 '11 17:04

knorv


People also ask

What characters are in \W regex?

\w (word character) matches any single letter, number or underscore (same as [a-zA-Z0-9_] ). The uppercase counterpart \W (non-word-character) matches any single character that doesn't match by \w (same as [^a-zA-Z0-9_] ). In regex, the uppercase metacharacter is always the inverse of the lowercase counterpart.

What does \W include?

\w stands for “word character”. It always matches the ASCII characters [A-Za-z0-9_]. Notice the inclusion of the underscore and digits.

Does regex work with Unicode?

This will make your regular expressions work with all Unicode regex engines. In addition to the standard notation, \p{L}, Java, Perl, PCRE, the JGsoft engine, and XRegExp 3 allow you to use the shorthand \pL. The shorthand only works with single-letter Unicode properties.

What is alphanumeric regex?

A regular expression for an alphanumeric string checks that the string contains lowercase letters a-z , uppercase letters A-Z , and numbers 0-9 . Optional quantifiers are used to specify a string length. And the code that does all this looks like this: /^[a-zA-Z0-9]+$/


2 Answers

perldoc perlunicode says

Character classes in regular expressions match characters instead of bytes and match against the character properties specified in the Unicode properties database. \w can be used to match a Japanese ideograph, for instance.

So it looks like the answer to your question is "yes".

However, you might want to use the \p{} construct to directly access specific Unicode character properties. You can probably use \p{L} (or, shorter, \pL) for letters and \pN for numbers and feel a little more confident that you'll get exactly what you want.

like image 179
CanSpice Avatar answered Oct 11 '22 08:10

CanSpice


Yes and no.

If you want all alphanumerics, you want [\p{Alphabetic}\p{GC=Number}]. The \w contains both more and less than that. It specifically excludes any \pN which is not \p{Nd} nor \p{Nl}, like the superscripts, subscripts, and fractions. Those are \p{GC=Other_Number}, and are not included in \w.

Because unlike most regex systems, Perl complies with Requirement 1.2a, “Compatibility Properties” from UTS #18 on Unicode Regular Expressions, then assuming you have Unicode strings, a \w in a regex matches any single code point that has any of the following four properties:

  1. \p{GC=Alphabetic}
  2. \p{GC=Mark}
  3. \p{GC=Connector_Punctuation}
  4. \p{GC=Decimal_Number}

Number 4 above can be expressed in any of these ways, which are all considered equivalent:

  • \p{Digit}
  • \p{General_Category=Decimal_Number}
  • \p{GC=Decimal_Number}
  • \p{Decimal_Number}
  • \p{Nd}
  • \p{Numeric_Type=Decimal}
  • \p{Nt=De}

Note that \p{Digit} is not the same as \p{Numeric_Type=Digit}. For example, code point B2, SUPERSCRIPT TWO, has only the \p{Numeric_Type=Digit} property and not plain \p{Digit}. That is because it is considered a \p{Other_Number} or \p{No}. It does, however, have the \p{Numeric_Value=2} property as you would imagine.

It’s really point number 1 above, \p{Alphabetic} ,that gives people the most trouble. That’s because they too often mistakenly think it is somehow the same as \p{Letter} (\pL), but it is not.

Alphabetics include much more than that, all because of the \p{Other_Alphabetic} property, as this in turn includes some but not all \p{GC=Mark}, all of \p{Lowercase} (which is not the same as \p{GC=Ll} because it adds \p{Other_Lowercase}) and all of \p{Uppercase} (which is not the same as \p{GC=Lu} because it adds \p{Other_Uppercase}).

That’s how it pulls in \p{GC=Letter_Number} like Roman numerals and also all the circled letters, which are of type \p{Other_Symbol} and \p{Block=Enclosed_Alphanumerics}.

Aren’t you glad we get to use \w? :)

like image 39
tchrist Avatar answered Oct 11 '22 06:10

tchrist