Eh bien, il y a plusieurs façons d'aborder ce problème. L'one-way est de capturer les articles que vous voulez exclure, trouver leurs décalages et longueurs et simplement extraire ces pièces de la chaîne originale et tout ce qui vous reste sont les parties en dehors des étiquettes.
est ici une fonction à titre d'exemple:
<?php
function match_all_except ($pattern, $string)
{
preg_match_all($pattern, $string, $match, PREG_OFFSET_CAPTURE);
$parts = array();
$pos = 0;
foreach ($match[0] as $info)
{
$parts[] = substr($string, $pos, $info[1] - $pos);
$pos = $info[1] + strlen($info[0]);
}
$parts[] = substr($string, $pos);
return $parts;
}
$string = 'one<? foo ?>two<? bar ?>three';
$parts = match_all_except('/<\?.*?\?>/s', $string);
// Will output "one, two, three, "
foreach ($parts as $outside)
{
echo "$outside, ";
}
?>
Vous pouvez également utiliser cette expression régulière /\G(?=.)((?:(?!<\?).)*)(?:<\?((?!\?>).)*(\?>|$)|$)/s
dans preg_match_all
pour capturer toutes les parties en dehors des balises dans le sous-motif un. Bien que, il peut avoir ses propres difficultés, si les étiquettes ne sont pas égalées dans le document.
Par exemple,
<?php
$string = 'one<? foo ?>two<? bar ?>three';
preg_match_all('/\G(?=.)((?:(?!<\?).)*)(?:<\?((?!\?>).)*(\?>|$)|$)/s', $string, $match);
// Will output "one, two, three, "
foreach ($match[1] as $outside)
{
echo "$outside, ";
}
?>
Pendant ce temps je remarquai que "(. *)" Ne correspond pas tout (par exemple des sauts de ligne ne correspondent pas. "([\ S \ s] *?)" – murze