note 47483 added to function.preg-match-all

From: Date: Wed, 17 Nov 2004 19:00:20 +0000
Subject: note 47483 added to function.preg-match-all
Groups: php.notes 
Request: Send a blank email to php-notes+get-80653@lists.php.net to get a copy of this message
preg_match_all and substr_count have the unfortunate side effect of not being as greedy as they could be in case your pattern overlaps itself. For example, if you're looking for :1:2: and have several adjacent :1:2: in your string, every other match will be skipped because, after a match, the search resumes at n+1 and therefore skips the initial : in the immediately adjacent match. Consider: :1:2:1:2:1:2:3:4:5:1:2: There are 4 instances of :1:2: in this string. preg_match_all and substr_count will find the first, third and fourth, but skip the second one at position 4, because once the one at position 0 is matched, matching resumes at position 5 (0 + length of match), i.e. the "1" character, and so it doesn't find the :1:2: at position 4. One workaround is to scan the string as follows: <? $ln = ":1:2:1:2:1:2:3:4:5:1:2:"; $pattern = ":1:2:"; $theCt = 0; $i = 0; while($i < strlen($ln)) { $found = strpos(substr($ln, $i), $pattern); if ($found !== false) { ++$theCt; $i += $found + strlen($pattern - 1); } else ++$i; } print "manual scan found ".$theCt." instances\n"; print "substr_count found ".substr_count($ln, $pattern)." instances\n"; preg_match_all("/".addslashes($pattern)."/", $ln, $matches); print "preg_match_all found ".count($matches[0])." instances\n"; ?> ---- Manual Page -- http://www.php.net/manual/en/function.preg-match-all.php Edit -- http://master.php.net/manage/user-notes.php?action=edit+47483 Delete -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes Reason: bad code -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes&reason=bad+code Reason: spam -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes&reason=spam Reason: useless example -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes&reason=useless+example Reason: contains commercial links -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes&reason=contains+commercial+links Reason: useless note -- http://master.php.net/manage/user-notes.php?action=delete+47483&report=yes&reason=useless+note Reject -- http://master.php.net/manage/user-notes.php?action=reject+47483&report=yes Search -- http://master.php.net/manage/user-notes.php

« previous php.notes (#80653) next »