2008-10-13 7 views
54

Quel est le meilleur/le plus efficace pour extraire le texte entre parenthèses? Dire que je voulais obtenir la chaîne "texte" de la chaîne "ignorer tout sauf ce (texte)" de la manière la plus efficace possible.PHP: La meilleure façon d'extraire le texte entre parenthèses?

Jusqu'à présent, le meilleur que je suis venu avec c'est:

$fullString = "ignore everything except this (text)"; 
$start = strpos('(', $fullString); 
$end = strlen($fullString) - strpos(')', $fullString); 

$shortString = substr($fullString, $start, $end); 

est-il une meilleure façon de le faire? Je sais qu'en général utiliser regex a tendance à être moins efficace, mais à moins que je puisse réduire le nombre d'appels de fonction, peut-être que ce serait la meilleure approche? Pensées?

+0

Vous pourriez trouver ['s ($ fullString) -> entre (" (",") ")'] (https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/ Str.php # L412) utile, tel que trouvé dans [cette bibliothèque autonome] (https://github.com/delight-im/PHP-Str). – caw

Répondre

96

Je ferais juste une regex et en finirais avec. à moins que vous faites suffisamment d'itérations qu'il devient un énorme problème de performance, il est juste plus facile de code (et comprendre quand vous regardez en arrière sur elle)

$text = 'ignore everything except this (text)'; 
preg_match('#\((.*?)\)#', $text, $match); 
print $match[1]; 
+0

N'est-ce pas *? redondant? – Dimitry

+0

Non, ce n'est pas:. ne correspond qu'à un seul caractère. –

+1

pas nécessairement,? est un match paresseux. sans cela, une chaîne comme 'ignore (tout) excepté ce (texte)', la correspondance finirait par être 'tout simplement' excepté ceci (texte ' – Owen

10

Donc, en fait, le code affiché ne fonctionne pas: substr()'s les paramètres sont $ string, $ start et $ longueur, et strpos()'s les paramètres sont $haystack, $needle. Légèrement modifié:

$str = "ignore everything except this (text)"; 
$start = strpos($str, '('); 
$end = strpos($str, ')', $start + 1); 
$length = $end - $start; 
$result = substr($str, $start + 1, $length - 1);

Quelques subtilités: je $start + 1 dans le paramètre offset afin d'aider PHP tout en faisant sortir la recherche strpos() sur la deuxième parenthèse; nous incrémentons $start et réduisons $length pour exclure les parenthèses de la correspondance.

De plus, il n'y a pas de vérification d'erreur dans ce code: vous devez vous assurer que $start et $end ne sont pas faux avant d'exécuter le substr.

En ce qui concerne l'utilisation de strpos/substr par rapport à regex; Au niveau de la performance, ce code battra une expression régulière. C'est un peu plus verbeux cependant. Je mange et respire strpos/substr, donc cela ne me dérange pas trop, mais quelqu'un d'autre peut préférer la compacité d'une regex.

4

Utilisez une expression régulière:

if(preg_match('!\(([^\)]+)\)!', $text, $match)) 
    $text = $match[1]; 
2

Ceci est un exemple de code pour extraire tout le texte entre « [ » et « ] » et stocker 2 tableaux distincts (ie texte entre parenthèses dans un tableau et texte entre parenthèses l'extérieur dans un autre tableau)

function extract_text($string) 
    { 
    $text_outside=array(); 
    $text_inside=array(); 
    $t=""; 
    for($i=0;$i<strlen($string);$i++) 
    { 
     if($string[$i]=='[') 
     { 
      $text_outside[]=$t; 
      $t=""; 
      $t1=""; 
      $i++; 
      while($string[$i]!=']') 
      { 
       $t1.=$string[$i]; 
       $i++; 
      } 
      $text_inside[] = $t1; 

     } 
     else { 
      if($string[$i]!=']') 
      $t.=$string[$i]; 
      else { 
       continue; 
      } 

     } 
    } 
    if($t!="") 
    $text_outside[]=$t; 

    var_dump($text_outside); 
    echo "\n\n"; 
    var_dump($text_inside); 
    } 

sortie: extract_text ("? bonjour comment allez-vous"); produira:

array(1) { 
    [0]=> 
    string(18) "hello how are you?" 
} 

array(0) { 
} 

extract_text ("bonjour [http://www.google.com/test.mp3] comment allez-vous?"); produira

array(2) { 
    [0]=> 
    string(6) "hello " 
    [1]=> 
    string(13) " how are you?" 
} 


array(1) { 
    [0]=> 
    string(30) "http://www.google.com/test.mp3" 
} 
+0

+1 mais comment faire la même chose pour [* et *] ? Parce que [] seulement peut-être utilisé sur html par exemple. – Mike

0

Cette fonction peut être utile.

public static function getStringBetween($str,$from,$to, $withFromAndTo = false) 
    { 
     $sub = substr($str, strpos($str,$from)+strlen($from),strlen($str)); 
     if ($withFromAndTo) 
     return $from . substr($sub,0, strrpos($sub,$to)) . $to; 
     else 
     return substr($sub,0, strrpos($sub,$to)); 
    } 
    $inputString = "ignore everything except this (text)"; 
    $outputString = getStringBetween($inputString, '(', ')')); 
    echo $outputString; 
    //output will be test 

    $outputString = getStringBetween($inputString, '(', ')', true)); 
    echo $outputString; 
    //output will be (test) 

strpos() => qui est utilisé pour trouver la position de la première occurrence dans une chaîne.

strrpos() => qui est utilisé pour trouver la position de la première occurrence dans une chaîne.