note 81247 deleted from function.preg-match-all by felipe
| From: | felipe@php.net | Date: | Sun, 23 Mar 2008 22:57:20 +0000 |
| Subject: | note 81247 deleted from function.preg-match-all by felipe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-137384@lists.php.net to get a copy of this message | ||
Note Submitter: fcmodz ET yahoo bot capow!
----
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>';
*/
?>