web-dev-qa-db-fra.com

Obtenir du contenu entre deux chaînes PHP

Quel est le meilleur moyen d’obtenir le contenu entre deux chaînes, par ex.

ob_start();
include('externalfile.html'); ## see below
$out = ob_get_contents();
ob_end_clean();

preg_match('/{FINDME}(.|\n*)+{\/FINDME}/',$out,$matches);
$match = $matches[0];

echo $match;

## I have used .|\n* as it needs to check for new lines. Is this correct?

## externalfile.html

{FINDME}
Text Here
{/FINDME}

Pour une raison quelconque, cela semble fonctionner à un endroit de mon code et pas à un autre. Est-ce que j'y vais de la bonne manière? Ou y a-t-il un meilleur moyen?

Est-ce que le tampon de sortie est aussi le moyen de faire ceci ou file_get_contents?

Merci d'avance!

20
Lizard
  • Utilisez # au lieu de / pour ne pas leur échapper.
  • Le modificateurs fait que . et \s incluent également les nouvelles lignes.
  • { et } ont diverses fonctionnalités, allant de n à m fois dans {n,m}.
  • Les bases

    preg_match('#\\{FINDME\\}(.+)\\{/FINDME\\}#s',$out,$matches);
    
  • Le avancé pour diverses balises, etc. (le style n'est pas si agréable par le javascript).

    $delimiter = '#';
    $startTag = '{FINDME}';
    $endTag = '{/FINDME}';
    $regex = $delimiter . preg_quote($startTag, $delimiter) 
                        . '(.*?)' 
                        . preg_quote($endTag, $delimiter) 
                        . $delimiter 
                        . 's';
    preg_match($regex,$out,$matches);
    

Mettre ce code dans une fonction

  • Pour tout fichier pour lequel vous ne souhaitez pas exécuter de code stray php, vous devez utiliser file_get_contents. inclure/exiger ne devrait même pas être une option là-bas.
39
OIS

Vous pouvez aussi bien utiliser substr et strpos pour cela.

$startsAt = strpos($out, "{FINDME}") + strlen("{FINDME}");
$endsAt = strpos($out, "{/FINDME}", $startsAt);
$result = substr($out, $startsAt, $endsAt - $startsAt);

Vous aurez besoin d'ajouter une vérification d'erreur pour gérer le cas où FINDME n'est pas utilisé.

40
Adam Wright

J'adore ces deux solutions

function GetBetween($content,$start,$end)
{
    $r = explode($start, $content);
    if (isset($r[1])){
        $r = explode($end, $r[1]);
        return $r[0];
    }
    return '';
}


function get_string_between($string, $start, $end){
    $string = " ".$string;
    $ini = strpos($string,$start);
    if ($ini == 0) return "";
    $ini += strlen($start);   
    $len = strpos($string,$end,$ini) - $ini;
    return substr($string,$ini,$len);
}

J'ai également fait peu de points de repère également avec les deux solutions ci-dessus et les deux donnent presque le même temps. Vous pouvez aussi le tester. J'ai donné aux deux fonctions un fichier à lire qui contenait environ 60000 caractères (revu avec le nombre de mots de Mme Word).

$startTime = microtime(true);
GetBetween($str, '<start>', '<end>');
echo "Explodin Function took: ".(microtime(true) - $startTime) . " to finish<br />";

$startTime = microtime(true);
get_string_between($str, '<start>', '<end>');
echo "Subsring Function took: ".(microtime(true) - $startTime) . " to finish<br />";
4
Abdul Jabbar Dumrai

J'aime éviter d'utiliser si possible regex, voici une solution alternative pour extraire toutes les chaînes entre deux chaînes et renvoie un tableau.

function getBetween($content, $start, $end) {
    $n = explode($start, $content);
    $result = Array();
    foreach ($n as $val) {
        $pos = strpos($val, $end);
        if ($pos !== false) {
            $result[] = substr($val, 0, $pos);
        }
    }
    return $result;
}
print_r(getBetween("The quick brown {{fox}} jumps over the lazy {{dog}}", "{{", "}}"));

Résultats :

Array
(
    [0] => fox
    [1] => dog
)
1
Donovan P

Les sauts de ligne peuvent causer des problèmes dans RegEx, essayez de les supprimer ou de les remplacer par\n avant traitement.

1
Cem Kalyoncu

Ceci est une solution PHP qui renvoie les chaînes trouvées entre les balises dans une botte de foin. Cela fonctionne, mais je n'ai pas testé l'efficacité. J'avais besoin de ça et j'ai été inspiré par la réponse d'Adam Wright sur cette page.

Retourne un tableau () contenant toutes les chaînes trouvées entre $ tag et $ end_symbold. $ Tag dans $ haystack, ou FALSE si aucune balise $ end_symbol. $ N'a été trouvée, donc aucune paire de balises n'existe dans $ haystack.

function str_between_tags($haystack, $tag, $end_symbol){
    $c_end_tags = substr_count($haystack, $end_symbol.$tag);
    if(!$c_end_tags) return FALSE;

    for($i=0; $i<$c_end_tags; $i++){
        $p_s = strpos($haystack, $tag, (($p_e)?$p_e+strlen($end_symbol.$tag):NULL) ) + strlen($tag );
        $p_e = strpos($haystack, $end_symbol.$tag, $p_s);
        $result[] = substr($haystack, $p_s, $p_e - $p_s);
    }
    return $result;
}
0
dalv lexa
function getInbetweenStrings($start, $end, $str){
    $matches = array();
    $regex = "/$start([a-zA-Z0-9_]*)$end/";
    preg_match_all($regex, $str, $matches);
    return $matches[1];
}


$str = "C://@@ad_custom_attr1@@/@@upn@@/@@samaccountname@@";
$str_arr = getInbetweenStrings('@@', '@@', $str);

print_r($str_arr);
0
Ravi Verma