note 108927 added to regexp.reference.recursive

From: Date: Wed, 06 Jun 2012 04:18:43 +0000
Subject: note 108927 added to regexp.reference.recursive
Groups: php.notes 
Request: Send a blank email to php-notes+get-188414@lists.php.net to get a copy of this message
The order of non-mutually exclusive alternatives within a recursed sub-pattern is important. <?php $pattern = '/^(?<octet>[01]?\d?\d|2[0-4]\d|25[0-5])(?:\.(?P>octet)){3}$/'; ?> You might expect that this pattern will match any IP address in dotted-decimal notation (e.g. '123.45.67.89'). The pattern is intended to match four octets in the following ranges: 0-9, 00-99 & 000-255, each separated by a single dot. However, only the first octet can include values from 200-255; the remainder can only have values less than 200. The reason for this is that if the rest of the pattern fails, recursion is not back-tracked into to find an alternative match. The first part of the sub-pattern will match the first two digits of any octet from 200-255. The rest of the pattern will then fail because the third digit in the octet does not match either '\.' or '$'. <?php var_export(preg_match($pattern, '255.123.45.67')); // 1 (true) var_export(preg_match($pattern, '255.200.45.67')); // 0 (false) var_export(preg_match($pattern, '255.123.45.200')); // 0 (false) ?> The correct pattern is: <?php $pattern = '/^(?<octet>25[0-5]|2[0-4]\d|[01]?\d?\d)(?:\.(?P>octet)){3}$/'; ?> Note that the first two alternatives are mutually exclusive so their order is unimportant. The third alternative, however, is not mutually exclusive but it will now only match when the first two fail. <?php var_export(preg_match($pattern, '255.123.45.67')); // 1 (true) var_export(preg_match($pattern, '255.200.45.67')); // 1 (true) var_export(preg_match($pattern, '255.123.45.200')); // 1 (true) ?> ---- Server IP: 113.20.13.217 Probable Submitter: 202.59.29.222 ---- Manual Page -- http://www.php.net/manual/en/regexp.reference.recursive.php Edit -- https://master.php.net/note/edit/108927 Del: integrated -- https://master.php.net/note/delete/108927/integrated Del: useless -- https://master.php.net/note/delete/108927/useless Del: bad code -- https://master.php.net/note/delete/108927/bad+code Del: spam -- https://master.php.net/note/delete/108927/spam Del: non-english -- https://master.php.net/note/delete/108927/non-english Del: in docs -- https://master.php.net/note/delete/108927/in+docs Del: other reasons-- https://master.php.net/note/delete/108927 Reject -- https://master.php.net/note/reject/108927 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#188414) next »