2010-03-18 12 views
0

J'utiliseTrouver tout ce qui est pas entre les balises spécifiques

preg_match_all('/<?(.*)?>/', $bigString, $matches, PREG_OFFSET_CAPTURE); 

pour trouver le contenu de tout entre <? et ?>

Maintenant, je voudrais trouver tout ce qui est pas entre <? et ?>

J'essaie avec

preg_match_all('/^(<?(.*)?>)/', $bigString, $nonmatches, PREG_OFFSET_CAPTURE); 

mais cela ne semble pas fonctionner ...

+0

Pendant ce temps je remarquai que "(. *)" Ne correspond pas tout (par exemple des sauts de ligne ne correspondent pas. "([\ S \ s] *?)" – murze

Répondre

0

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, "; 
} 

?> 
+0

Bonjour, la solution regex donne une erreur de serveur interne sur mon serveur, mais la fonction fonctionne parfaitement pour moi! Merci! – murze

0

approche non regex

$str=<<<EOF 
1 some words 
1 some more words 
<? 
blah blah 
blah blah 
?> 
2 some words 
2 some words <? 
jdf 
sdf ?> 
asdf 
sdfs 
EOF; 

$s = explode('?>',$str); 
foreach($s as $v){ 
    $m = strpos($v,'<?'); 
    if($m!==FALSE){ 
    print substr($v,0,$m)."\n"; 
    } 
} 
print end($s); 

de sortie

$ php test.php 
1 some words 
1 some more words 


2 some words 
2 some words 

asdf 
sdfs 
+0

Salut, cette approche fonctionne, mais il y a quelques petits détails qui ne sont pas résolus Le texte après le dernier?> n'est pas trouvé, je peux facilement résoudre ce moi-même avec un supplément si. Mais je ' Je voudrais aussi avoir la position de départ de la chaîne trouvée dans la chaîne d'origine Dans mon exemple dans la question d'origine j'utilise PREG_OFFSET_CAPTURE pour y arriver Avec l'approche non-regex, est-ce que je peux obtenir la position de départ de la chaîne trouvée? – murze

+0

vous pouvez toujours faire un 'preg_match' sur' ghostdog74