2010-05-12 6 views
1

Tenez compte des chaîne suivante:motif remplacement complexe en utilisant la fonction preg_replace PHP en ignorant les chaînes entre guillemets

ceci est une chaîne où certains mots-clés sont disponibles. 'J'ai besoin de formater les KEYWORDS de la chaîne'

Dans les mots clés de chaîne ci-dessus sont STRING et

Maintenant, je dois obtenir une sortie comme suit:

this is a <b>STRING</b> <b>WHERE</b> some keywords ARE available. 'i need TO format the KEYWORDS from the STRING' 

Alors que la sortie html sera comme:

Ceci est un STRING OERE certains mots-clés sont disponibles. «J'ai besoin de formater les KEYWORDS de la chaîne »

Notez que les mots-clés dans une chaîne entre guillemets (« ... ») seront ignorées. Dans l'exemple ci-dessus j'ai ignoré le mot clé STRING dans la chaîne entre guillemets.

S'il vous plaît donner un script version modifiée du PHP suivant pour que je puisse avoir mon résultat désiré comme ci-dessus:

$patterns = array('/STRING/','/WHERE/'); 
$replaces = array('<b>STRING</b>', '<b>WHERE</b>'); 
$string = "this is a STRING WHERE some keywords ARE available. 'i need TO format the KEYWORDS from the STRING'"; 
preg_replace($patterns, $replaces, $string); 

Répondre

2

Cela fonctionnera avec votre exemple de chaîne, mais il y aura des problèmes avec des chaînes plus compliquées, par exemple celles contenant des mots avec des apostrophes. Quoi qu'il en soit, il peut être utilisé comme point de départ.

$keywords = array("STRING", "WHERE"); 
$regexp = '/(\'[^\']+\')|\b(' . implode('|', $keywords) . ')\b/e'; 
preg_replace($regexp, "strlen('\\2') ? '<b>\\2</b>' : '\\0'", $string); 
+0

WOW! belle solution. Pourriez-vous s'il vous plaît expliquer quelle est la signification de \ b et \\ 2. Bien que, si je considère une autre citation comme '' y compris '' (signifie deux citations), quel sera le script? Merci beaucoup ... :) –

+0

\ b - limite de mot, c'est-à-dire position dans la chaîne où l'un des caractères est une lettre (ou chiffre ou "_"), l'autre - pas une lettre. \ 0, \ 1, \ 2 - le texte capturé par le nième motif entre parenthèses: \ 1 - contenu de la première paire de parenthèses regex (dans ce cas - la sous-chaîne citée), \ 2 - contenu de la seconde pair (dans ce cas - l'un des mots-clés), \ 0 - toute la chaîne correspondante (dans ce cas, il est égal à \ 1 ou \ 2) –

+0

Mais cette solution ignore-t-elle le texte contenu dans une paire de guillemets simples, selon le PO? –

0

Essayez quelque chose comme:

$keywords = array(
    'STRING' , 
    'WHERE' , 
    'KEYWORDS' 
); 
$keywordsRE = array(); 
foreach($keywords as $w) { 
    $keywordsRE[] = '/\b('.$w.')\b/'; 
} 
$string = "this is a STRING WHERE some keywords KEYWORDS ARE available. 'i need TO format the KEYWORDS from the STRING'"; 
$stringParts = explode("'" , $string); 
foreach($stringParts as $k => $v) { 
    if(!($k%2)) 
    $stringParts[$k] = preg_replace($keywordsRE , '<b>$1</b>' , $v); 
} 
$stringReplaced = implode("'" , $stringParts); 

Répétition de la lecture les mots-clés (avec les mêmes changements) sont un peu redondants - l'utilisation d'une expression régulière vous permet d'appliquer ces mêmes changements (dans ce cas, envelopper les correspondances dans <b></b> tags) pour tous les matchs.

+0

C'est une solution imparfaite, et un peu hacky, mais ça marche. Et j'ai changé le contenu de la variable '$ string' pour le prouver (ie" KEYWORDS "étant vu à l'intérieur et à l'extérieur de la zone exclue) –