note 81247 added to function.preg-match-all
| From: | fcmodzETyahoobotcapow! at osu1 dot php dot net | Date: | Wed, 20 Feb 2008 02:33:31 +0000 |
| Subject: | note 81247 added to function.preg-match-all | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-136294@lists.php.net to get a copy of this message | ||
Here's a function to identical to preg_match_all with the offset flag enabled, except it allows
you to search through data while ignoring other data that matches a certain pattern. An example use
is to search through html data with all the tags removed, you can see which text is next to others,
and get the matches of your search pattern in the original data before the tags were stripped.
RETURNS:
false on 0 matches found
an array identical to default array returned with preg_match_all() with the PREG_OFFSET_CAPTURE flag
enabled, except there is extra item in match array which gives the match including the ignored data
ie:
[0] match that doesn't include ignored data
[1] offset of match in original data ($hay)
[2] match that does include ignored data
<?php
function preg_match_ignore_pat($searchPat, $ignorePat, $hay) {
$matches = preg_match_all($ignorePat, $hay, $out);
if ($matches && !empty($out[0])) {
$splitArr = preg_split($ignorePat, $hay, -1, PREG_SPLIT_OFFSET_CAPTURE);
$splitArr2 = preg_split($ignorePat, $hay);
$searchHay = implode('', $splitArr2);
$findPhrase = preg_match_all($searchPat, $searchHay, $phraseOut, PREG_OFFSET_CAPTURE);
//phrase was found
if ($findPhrase && !empty($phraseOut[0])) {
//make offArr
$newOff = 0;
foreach ($splitArr as $k => $pieceInfo) {
$offArr[$newOff] = $pieceInfo[1];
$newOff = $newOff + strlen($pieceInfo[0]);
}
//find real offsets of matches of found phrase in haystack
foreach ($phraseOut as $subKey => $subArr) {
foreach ($subArr as $matchInfo) {
//newMatchRealOff = closestRealOff + (newMatchNewOff - closestNewOff)
//find real off, start of match
$newOff_start = $matchInfo[1];
$x = $newOff_start + 1;
do {
$x--;
} while(!array_key_exists($x, $offArr));
$realOff_start = $offArr[$x] + ($newOff_start - $x);
//find real off, end of match
$newOff_end = ($matchInfo[1] + strlen($matchInfo[0]))-1;
$x = $newOff_end + 1;
do {
$x--;
} while(!array_key_exists($x, $offArr));
$realOff_end = $offArr[$x] + ($newOff_end - $x);
$len = ($realOff_end - $realOff_start) + 1;
//out array
$pOut[$subKey][] = array($matchInfo[0], $realOff_start, substr($hay, $realOff_start, $len));
}
}
return $pOut;
} else {
//phrase wasn't found
return false;
}
} else {
//the ignore data is not present in the haystack, so search through it normally with
preg_match_all
$matches = preg_match_all($searchPat, $hay, $out, PREG_OFFSET_CAPTURE);
if ($matches && !empty($out[0])) {
return $out;
} else {
return false;
}
}
}
#example use 1
echo '<pre>';
$ignoreDataPat = '~<[^>]+>~';
$searchPat = '~this\s*(?P<first>hello)\s*(?P<second>whatever)\s*man~i';
$hay = '<b>this</b> hello <span id="this"> what<html tag>ever
</span> man whatever';
$arr = preg_match_ignore_pat($searchPat, $ignoreDataPat, $hay);
print_r($arr);
echo '</pre>';
*/
?>
----
Server IP: 209.41.74.194
Probable Submitter: 68.53.235.219
----
Manual Page -- http://www.php.net/manual/en/function.preg-match-all.php
Edit -- https://master.php.net/note/edit/81247
Del: integrated -- https://master.php.net/note/delete/81247/integrated
Del: useless -- https://master.php.net/note/delete/81247/useless
Del: bad code -- https://master.php.net/note/delete/81247/bad+code
Del: spam -- https://master.php.net/note/delete/81247/spam
Del: non-english -- https://master.php.net/note/delete/81247/non-english
Del: in docs -- https://master.php.net/note/delete/81247/in+docs
Del: other reasons-- https://master.php.net/note/delete/81247
Reject -- https://master.php.net/note/reject/81247
Search -- https://master.php.net/manage/user-notes.php