note 107520 deleted from regexp.reference.onlyonce by tularis
| From: | tularis@php.net | Date: | Wed, 15 Feb 2012 14:59:37 +0000 |
| Subject: | note 107520 deleted from regexp.reference.onlyonce by tularis | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-186146@lists.php.net to get a copy of this message | ||
Note Submitter: Zeus
----
For what it's worth, here's the expression I came up with that (I think) matches
everything the original does, and nothing else, while being efficient.
((?>[^\d<!?]+)|<((?>\d+)>)?|(?>[!?]+))*(?<=[!?])
It searches for any number of A: a series of anything besides a digit, <, !, or ?, and/or B:
<, optionally followed by a series of digits and >, and/or C: one or more ? and/or ! . It then
uses a look-behind to check that the end of the string is ! or ?. The series of digits, the series
of (not-digit, not-<,!,?), and the series of ? and/or ! are all once-only.
((?>\D+)|<\d+>)*[!?] wouldn't work, because the once-only group could swallow up ! or
? at the end, and also the < that would start the alternate. The third group (?>[!?]+) is
required in order to match the string when other characters (besides digits) follow the pattern.
Example: aaaaa<123>!?!?!---
If the expression only needs to match a whole string, then the following will work.
^((?>[^\d<]+)|<((?>\d+)>)?)*(?<=[!?])$