2009-10-23 7 views
0

Salut à tous im en train d'écrire une fonction « affichage du code php » (sortie peut être vu à http://www.actwebdesigns.co.uk/web-design-mansfield/php-functions/display-code-function.php)Preg match sur le code d'affichage php

Im ayant des problèmes avec le schéma de couleurs qui se fait par l'expression régulière. Le 2 en particulier sont:

cordes:

$line = preg_replace("#(\s|\()(\"[^\"]*\")(\,|\))#is", "\\1<span class=\"string\">\\2</span>\\3", $line); 

(et essayer)

#\"((?!(?:\"\s*;)|(?:\"\s*,)).)*#is 

et fonctions:

$line = preg_replace("#(\s*)(@?|!?[a-z]+(?:[a-z]|[0-9]|_)*)(\s*)\(([^\)]*)\)#is", "\\1<span class=\"function\">\\2\\3</span>(\\4)", $line); 

(si une fonction est à l'intérieur d'une fonction, il ne change pas de couleur

+0

Vous faites cela pour l'amélioration de soi ou étiez-vous au courant de 'highlight_string()'? –

Répondre

0

pourquoi si compliqué? Utilisez hightlight_string(). ... et la mise en tampon de sortie et ini_set(), si vous avez besoin de changer sa sortie.

+0

ne semble pas vraiment faire ce que im après ... ne semble pas mettre en évidence les fonctions et ainsi de suite et la sortie est partout. –

0

À propos de votre chaîne regex: vous le dites est une chaîne si et seulement si elle est précédée par un espace blanc ou un ( et il est directement suivi d'un , ou ). Aiguilles à dire, ce n'est pas correct. Vous ne manquez pas des chaînes comme: (il y a beaucoup plus, et que dire « ici-docs »)

$s = "123";  // ends with a ; 
$s = "ab\"cd"; // contains an escaped double quote 
$t = 'efg' ; // is surrounded by single quotes 

pour ne citer que trois.

Pour prendre en compte fixer les cas ci-dessus, essayez quelque chose comme ceci:

$line = 's = "123"; t = "ab\\\\\\"cd"; u = \'efg\' ; v = \'ef\\\'g\' '; 
echo $line . "\n"; 
echo preg_replace('/((["\'])(?:\\\\.|(?:(?!\2).|[^\\\\"\'\r\n]))*\2)/', '<span class="string">$1</span>', $line); 
/* output: 
s = "123"; t = "ab\\\"cd"; u = 'efg' ; v = 'ef\'g' 
s = <span class="string">"123"</span>; t = <span class="string">"ab\\\"cd"</span>; u = <span class="string">'efg'</span> ; v = <span class="string">'ef\'g'</span> 
*/ 

Une brève explication:

(      # start group 1 
    (["\'])    # match a single- or double quote and store it in group 2 
    (?:     #  start non-matching group 1 
    \\\\.    #  match a double quote followed by any character (except line breaks) 
    |     #  OR 
    (?:     #  start non-matching group 2 
     (?!\2).   #  a character other than what is captured in group 2 
     |     #  OR 
     [^\\\\"\'\r\n]  #  any character except a backslash, double quote, single quote or line breaks 
    )     #  end non-matching group 2 
)*      # end non-matching group 1 and match it zero or more times 
    \2      # the quote captured in group 2 
)      # end group 1 

ensuite quelques commentaires au sujet de votre deuxième regex: vous essayez d'abord de faire correspondre zéro ou plus caractères espace blanc. Cela peut être omis en toute sécurité car si aucun espace blanc n'existe vous auriez toujours une correspondance. Vous pouvez utiliser un \b (limite de mot) avant de faire correspondre le nom de la fonction . En outre, (?:[a-z]|[0-9]|_) peut être remplacé par (?:[a-z0-9_]). Et cette partie de votre regex: (@?|!?[a-z]+(?:[a-z]|[0-9]|_)*) qui est le même que:

(
    @? 
    | 
    !? 
    [a-z]+ 
    (?: 
    [a-z] 
    | 
    [0-9] 
    | 
    _ 
)* 
) 

seulement mieux dentelée pour voir ce qu'il fait. Si vous regardez de plus près, vous verrez que cela va correspondre juste @?, et puisque le @ est rendu optionnel par le ?, que une partie de votre regex trouvera une chaîne vide aussi. Pas ce à quoi tu t'attendais, hein? Après cela, je dois avouer que j'ai cessé de regarder cette regex plus, mieux le jeter .

Essayez quelque chose comme ça pour correspondre les noms de fonction:

'/\b[a-z_][a-z0-9_]*(?=\s*\()/i' 

Ce qui signifie:

\b   # a word boundary (the space between \w and \W) 
[a-z_]  # a letter or an underscore 
[a-z0-9_]* # a letter, digit or an underscore, zero or more times 
(?=   # start positive look ahead 
    \s*  # zero ore more white space characters 
    \(  # an opening parenthesis 
)   # end positive look ahead 

Ce dernier n'a pas été testé du tout, je laisse cela pour vous. Notez également que je connais très peu PHP, donc je peux le simplifier à l'excès, auquel cas il serait utile si vous fournissez quelques exemples d'extraits de code que vous voulez faire correspondre en tant que fonctions.

En outre, un mot d'avertissement, le code en utilisant l'analyse syntaxique regex-es peut être difficile, mais si vous ne utiliser pour effectuer la mise en évidence de petits extraits de code, vous devriez être bien. Lorsque les fichiers sources sont plus volumineux, vous pouvez voir une baisse des performances et vous devez faire certaines parties de vos expressions régulières "possessive" qui augmenteront considérablement le temps d'exécution de votre correspondance (en particulier sur les fichiers sources plus volumineux).

Enfin, vous êtes probablement en train de réinventer la roue. Il existe de nombreux surligneurs de code (bien testés) que vous pouvez utiliser. Je suppose que vous le savez déjà, mais je pensais que cela mériterait d'être mentionné.

Pour votre information, j'ai eu une bonne expérience avec celui-ci: http://shjs.sourceforge.net/doc/documentation.html