Regular expressions in Perl

Metacharacters

char meaning
^ beginning of string
$ end of string
. any character except newline
* match 0 or more times
+ match 1 or more times
? match 0 or 1 times; or: shortest match
| alternative
() grouping; "storing"
[ ] set of characters
{ } repetition modifier
\ quote or special

To present a metacharacter as a data character standing for itself, precede it with \ (e.g. \. matches the full stop character . only).

In the table above, the characters themselves, in the first column, are links to descriptions of characters in my The ISO Latin 1 character repertoire - a description with usage notes. Note that the physical appearance (glyph) of a character may vary from one device or program or font to another.

Repetition

a* zero or more a's
a+ one or more a's
a? zero or one a's (i.e., optional a)
a{m} exactly m a's
a{m,} at least m a's
a{m,n} at least m but at most n a's
repetition? same as repetition but the shortest match is taken

Read "a's" as "occurrences of strings, each of which matches the pattern a". Read repetition as any of the repetition expressions listed above it. Shortest match means that the shortest string matching the pattern is taken. The default is "greedy matching", which finds the longest match. The repetition? construct was introduced in Perl version 5.

Special notations with \

Single characters
\t tab
\n newline
\r return (CR)
\xhh character with hex. code hh
"Zero-width assertions"
\b "word" boundary
\B not a "word" boundary
Matching
\w matches any single character classified as a "word" character (alphanumeric or _)
\W matches any non-"word" character
\s matches any whitespace character (space, tab, newline)
\S matches any non-whitespace character
\d matches any digit character, equiv. to [0-9]
\D matches any non-digit character

Character sets: specialities inside [...]

Different meanings apply inside a character set ("character class") denoted by [...] so that, instead of the normal rules given here, the following apply:

[characters] matches any of the characters in the sequence
[x-y] matches any of the characters from x to y (inclusively) in the ASCII code
[\-] matches the hyphen character -
[\n] matches the newline; other single character denotations with \ apply normally, too
[^something] matches any character except those that [something] denotes; that is, immediately after the leading [ the circumflex ^ means "not" applied to all of the rest

Examples

expression matches...
abc abc (that exact character sequence, but anywhere in the string)
^abc abc at the beginning of the string
abc$ abc at the end of the string
a|b either of a and b
^abc|abc$ the string abc at the beginning or at the end of the string
ab{2,4}c an a followed by two, three or four b's followed by a c
ab{2,}c an a followed by at least two b's followed by a c
ab*c an a followed by any number (zero or more) of b's followed by a c
ab+c an a followed by one or more b's followed by a c
ab?c an a followed by an optional b followed by a c; that is, either abc or ac
a.c an a followed by any single character (not newline) followed by a c
a\.c a.c exactly
[abc] any one of a, b and c
[Aa]bc either of Abc and abc
[abc]+ any (nonempty) string of a's, b's and c's (such as a, abba, acbabcacaa)
[^abc]+ any (nonempty) string which does not contain any of a, b and c (such as defg)
\d\d any two decimal digits, such as 42; same as \d{2}
\w+ a "word": a nonempty sequence of alphanumeric characters and low lines (underscores), such as foo and 12bar8 and foo_1
100\s*mk the strings 100 and mk optionally separated by any amount of white space (spaces, tabs, newlines)
abc\b abc when followed by a word boundary (e.g. in abc! but not in abcd)
perl\B perl when not followed by a word boundary (e.g. in perlert but not in perl stuff)

Simple usage examples in Perl statements

These examples use very simple regexps only. The intent is just to show contexts where regexps might be used, as well as the effect of some "flags" to matching and replacements. Note in particular that matching is by default case-sensitive (Abc does not match abc unless specified otherwise).

s/foo/bar/;
replaces the first occurrence of the exact character sequence foo in the "current string" (in special variable $_) by the character sequence bar; for example, foolish bigfoot would become barlish bigfoot

s/foo/bar/g;
replaces any occurrence of the exact character sequence foo in the "current string" by the character sequence bar; for example, foolish bigfoot would become barlish bigbart

s/foo/bar/gi;
replaces any occurrence of foo case-insensitively in the "current string" by the character sequence bar (e.g. Foo and FOO get replaced by bar too)

if(m/foo/)...
tests whether the current string contains the string foo


EXPRESSION FUNCTION
/abc/ Matches abc anywhere within the string
/^abc/ Matches abc at the beginning of the string
/abc$/ Matches abc at the end of the string
/a|b/ Matches either a or b
/ab{m,n}c/ Matches an a followed by m-n b's, followed by c, where m,n are nonnegative integers, m>n. If the second number is omitted, such as /ab {m,}c/, the expression will match m or more b's.
/ab*c/ Matches an a followed by zero or more b's, followed by c.
/ab+c/ Matches an a followed by one or more b's followed by c.
/ab?c/ Matches an a followed by an optional b followed by c. In Perl 5, the expression: /ab*?c/matches an a followed by as few b's as possible.
/./ Matches any single character except a newline (\n) /a..d / matches a a followed by any two characters, followed by d.
/[abc]/ Matches any one of a or b or c. A pattern of /[abc]+/ matches strings such as abcab, acbc, abbac, and so on.
/\d/ Matches a digit. Multipliers can be used. (/\d+/ matches one or more digits.)
/\w/ Matches a character classified as a word.
/\s/ Matches a character classified as whitespace.
/\b/ Matches a word boundary or a backspace. /cde\b/ matches cde, but not cdef. However, \b matches a backspace character inside a class. that is, [\b].
/[^abc]/ Matches a character that is not in the class. /[^abc ]+/ will match a string such as defg.
/\D/ Matches a character that is not a digit.
/\W/ Matches a character that is not a word.
/\S/ Matches a character that is not whitespace.
/\B/ Requires that there is no word boundary. /perl\B/ matches perl, but not perl script.
/\*/ Matches the * character. Use the \ character to escape characters that have significance in a regular expression.
/(abc)/ Matches abc anywhere within the string, but the parentheses act as memory, storing abc in the variable $1.
/abc/i Ignores case. Matches either abc, Abc, ABc, and so on.

 

Basic Syntax of Regular Expressions
First of all, let's take a look at two special symbols: '^' and '$'. What they do is indicate the start and the end of a string, respectively, like this:
You can see that if you don't use either of the two characters we mentioned, as in the last example, you're saying that the pattern may occur anywhere inside the string -- you're not "hooking" it to any of the edges.
There are also the symbols '*', '+', and '?', which denote the number of times a character or a sequence of characters may occur. What they mean is: "zero or more", "one or more", and "zero or one." Here are some examples:
You can also use bounds, which come inside braces and indicate ranges in the number of occurences:
Note that you must always specify the first number of a range (i.e, "{0,2}", not "{,2}"). Also, as you might have noticed, the symbols '*', '+', and '?' have the same effect as using the bounds "{0,}", "{1,}", and "{0,1}", respectively.
Now, to quantify a sequence of characters, put them inside parentheses:
There's also the '|' symbol, which works as an OR operator:
A period ('.') stands for any single character:
Bracket expressions specify which characters are allowed in a single position of a string:
You can also list which characters you DON'T want -- just use a '^' as the first symbol in a bracket expression (i.e., "%[^a-zA-Z]%" matches a string with a character that is not a letter between two percent signs).
In order to be taken literally, you must escape the characters "^.[$()|*+?{\" with a backslash ('\'), as they have special meaning. On top of that, you must escape the backslash character itself in PHP3 strings, so, for instance, the regular expression "(\$|¥)[0-9]+" would have the function call: ereg("(\\$|¥)[0-9]+", $str) (what string does that validate?)
Just don't forget that bracket expressions are an exception to that rule--inside them, all special characters, including the backslash ('\'), lose their special powers (i.e., "[*\+?{}.]" matches exactly any of the characters inside the brackets). And, as the regex man pages tell us: "To include a literal ']' in the list, make it the first character (following a possible '^'). To include a literal '-', make it the first or last character, or the second endpoint of a range."
For completeness, I should mention that there are also collating sequences, character classes, and equivalence classes. I won't be getting into details on those, as they won't be necessary for what we'll need further down this article. You should refer to the regex man pages for more information.

Learning to Use Regular Expressions by Example
Validating Money Strings
Ok, we can now use what we've learned to work on something useful: a regular expression to check user input of an amount of money. A quantity of money can be written in four ways we can consider acceptable: "10000.00" and "10,000.00", and, without the cents, "10000" and "10,000". Let's begin with:
^[1-9][0-9]*$
That validates any number that doesn't start with a 0. But that also means the string "0" doesn't pass the test. Here's a solution:
^(0|[1-9][0-9]*)$
"Just a zero OR some number that doesn't start with a zero." We may also allow a minus sign to be placed before the number:
^(0|-?[1-9][0-9]*)$
That means: "a zero OR a possible minus sign and a number that doesn't start with a zero." Ok, let's not be so strict and let the user start the number with a zero. Let's also drop the minus sign, as we won't be needing it for the money string. What we could do is specify an optional decimal fraction part in the number:
^[0-9]+(\.[0-9]+)?$
It's implicit in the highlited construct that a period always comes with at least one digit, as a whole set. So, for instance, "10." is not validated, whereas "10" and "10.2" are.
^[0-9]+(\.[0-9]{2})?$
We specified that there must be exactly two decimal places. If you think that's too harsh, you can do the following:
^[0-9]+(\.[0-9]{1,2})?$
That allows the user to write just one number after the period. Now, as for the commas separating the thousands, we can put in:
^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$
"A set of 1 to 3 digits followed by zero or more sets of a comma and three digits." Easy enough, isn't it? But let's make the commas optional:
^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(\.[0-9]{1,2})?$
That's it. Don't forget that the '+' can be substituted by a '*' if you want empty strings to be accepted also (why?). And don't forget to escape the backslash for the function call (common mistake here). Now, once the string is validated, we strip off any commas with str_replace(",", "", $money) and typecast it to double so we can make math with it.

Validating E-mail Addresses
Ok, let's take on e-mail addresses. There are three parts in an e-mail address: the POP3 user name (everything to the left of the '@'), the '@', and the server name (the rest). Some think that the user name may contain upper or lowercase letters, digits, periods ('.'), minus signs ('-'), and underscore signs ('_'). Actually that is wrong and there can be a lot of other characters included, but this quasi rule applies to about 99% of the email addresses out there, so it is good enough for this example. That's also the case for the server name, except for underscore signs, which may not occur.
Now, you can't start or end a user name with a period, it doesn't seem reasonable. The same goes for the domain name. And you can't have two consecutive periods, there should be at least one other character between them. Let's see how we would write an expression to validate the user name part:
^[_a-zA-Z0-9-]+$
That doesn't allow a period yet. Let's change it:
^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*$
That says: "at least one valid character followed by zero or more sets consisting of a period and one or more valid characters."
To simplify things a bit, we can use the expression above with eregi(), instead of ereg(). Because eregi() is not sensitive to case, we don't have to specify both ranges "a-z" and "A-Z" -- one of them is enough:
^[_a-z0-9-]+(\.[_a-z0-9-]+)*$
For the server name it's the same, but without the underscores:
^[a-z0-9-]+(\.[a-z0-9-]+)*$
Done. Now, joining both expressions around the 'at' sign, we get:
^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$

Other uses
Extracting Parts of a String
ereg() and eregi() have a feature that allows us to extract matches of patterns from strings (read the manual for details on how to use that). For instance, say we want do get the filename from a path/URL string -- this code would be all we need:
ereg("([^\\/]*)$", $pathOrUrl, $regs);
echo $regs[1];
Advanced Replacing
ereg_replace() and eregi_replace() are also very useful: suppose we want to separate all words in a string by commas:
ereg_replace("[ \n\r\t]+", ",", trim($str));

  Some pages about Regular Expressions:

http://www.regular-expressions.info/ (general info about)

http://regexlib.com/Default.aspx (collection of samples ready to use)

http://en.wikipedia.org/wiki/Regular_expression (general use)

http://www.phpbuilder.com/columns/dario19990616.php3 (use in PHP)

http://weblogtoolscollection.com/regex/regex.php (in PHP)

http://www.webreference.com/programming/php/regexps/ (in PHP)

http://www.sitepoint.com/article/regular-expressions-php (in PHP)

http://www.sitepoint.com/article/286 (in Javascript)

http://sitescooper.org/tao_regexps.html

http://dev.mysql.com/doc/mysql/en/Regexp.html (in MySQL)

http://www.wellho.net/regex/mysql.html (in MySQL)

http://www.perl.com/doc/manual/html/pod/perlre.html (in Pearl)

http://www.pcre.org/ (Perl Compatible Regular Expressions)