Expressions régulières - Creole

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Expressions régulières - Creole

par Ouaibou » 02 juil. 2007, 18:40

Pfff deux fois que j'écris une réponse et que j'efface car je me rend compte au dernier moment d'un problème :roll:

En tout cas merci de ta réponse je vais essayé d'implémenter ce que tu m'as dit.

par naholyr » 02 juil. 2007, 16:02

Tu peux passer par un encodage/décodage.
Dans la fonction "processLinks" tu vas mettre (par exemple) ":§§" au lieu de "://".
Et une fois que tu es assuré qu'il n'y aura plus d'appel aux emphases (typiquement à la fin de la fonction "parse") tu vas faire un simple str_replace() pour remplacer ":§§" par "://".

Tu peux aussi faire pire, c'est ne pas décoder, et remplacer les "/" par "& #47;" qui sera parfaitement interprété par le navigateur. Par exemple <a href="http:& #47;& #47;www.paaymayin-nekudotayim.net& #47;index.php">Paamayim Nekudotayim</a> fonctionne très bien.

Note: j'ai mis un espace entre le & et le # pour que ce ne soit pas interprété dans mon message, il n'y est bien évidemment pas normalement.

Expressions régulières - Creole

par Ouaibou » 02 juil. 2007, 14:42

Bonjour,

Je suis de retour pour poser quelques questions sur les expressions régulières.

Ayant remarqué qu'il n'existe aucun script PHP implémentant la syntaxe Wiki définit par le groupe Creole (à part PEAR qui l'implémente mais en php4, et avec divers packages liés entre eux), je me suis décidé de réaliser une classe PHP5.

Les recommandations sont disponibles ici :

http://www.wikicreole.org/wiki/Creole1.0

J'ai donc commencé à écrire ceci :
<?php
class CreoleParser
{
	/**
	 * The rules in order to respect the Creole recommendations.
	 */
	private $rules = array(
			'Emphasis'  => array(
							'regex'		=> '#\/\/(.*?)\/\/#',
							'xhtml'		=> '<em>$1</em>',
							'type'		=> 'default'),
			'Headings'  => array(
							'regex'		=> '#^(={1,6})(.*?)(=+)#m',
							'type' 		=> 'callback'),
			'HorizontalLine'  => array(
							'regex'		=> '#-{4}#m',
							'xhtml'		=> '<hr />',
							'type'		=> 'default'),
			'Image' 	=> array(
							'regex'		=> '#{{(.*)(\|(.*))?}}#U',
							'type' 		=> 'callback'),
			'Links'  	=> array(
							'regex'		=> '#(^|\s)(\*\*|\/\/)(http(s)?|ftp):\/\/(.*)(\.[a-z]{2,4})(\*\*|\/\/)#m',
							'type'		=> 'callback'),
			'Strong'    => array(
							'regex' 	=> '#\*\*(.*?)\*\*#',
							'xhtml' 	=> '<strong>$1</strong>',
							'type'		=> 'default'),
			'Underline' => array(
							'regex' 	=> '#__(.*?)__#',
							'xhtml' 	=> '<ins>$1</ins>',
							'type'		=> 'default'),
			'Url'  => array(
							'regex'		=> '#\[\[(.*)(\|(.*))?\]\]#U',
							'type' 		=> 'callback'),
			);
	
	/**
	 * @type String
	 * Content the last parsed text.
	 */
	private $text = '';
	
	private function processHeadings($matches) {
    	$count = strlen($matches[1]);
    	return '<h' . $count . '>' . $matches[2] . '</h' . $count . '>';
	}
	
	private function processImage($matches) {
		$alt = $matches[3];
		$src = $matches[1];
		
		if (!$alt) {
			return '<img src=' . $src . ' />';
		} else {
			return '<img src="' . $src . '" alt="' . $alt . '" />';
		}
	}
	
	private function processLinks($matches) {
		$start_tag = $matches[2];
		$href = $matches[3] . '://' . $matches[5] . $matches[6];
		$end_tag = $matches[7];

		if (($start_tag == '**' && $end_tag == '**') ||
			($start_tag == '//' && $end_tag == '//')) {
			return $start_tag . '<a href="' . $href . '">' . $href . '</a>' . $end_tag;
		} else {
			return '<a href="' . $href . '">' . $href . '</a>';
		}
	}
	
	private function processUrl($matches)
	{
		$href = $matches[1];
		$title = $matches[3];
		
		$url = '<a href="' . $href . '"';
		
		if ($title) {
			$url .= ' title="' . $title . '"';
			$url .= '>' . $title . '</a>';
		} else {
			$url .= '>' . $href . '</a>';
		}		
		
		return $url;
	}
	
	public function parse($txt)
	{
		$this->text = $txt;
		
		foreach ($this->rules as $rule=>$values) {
			if ($values['type'] == 'default') {
				$this->text = preg_replace($values['regex'], $values['xhtml'], $this->text);
			}
			else {
				$this->text = preg_replace_callback($values['regex'], array($this, 'process'.$rule), $this->text);
			}
		}
		
		return $this->text;
	}
}
?>
Pour l'instant les règles implémentées (les plus simples) fonctionnent sauf pour une : "Links"
En effet celle-ci rentre en conflit avec l'emphase. J'ai utilisé une fonction de callback pour corriger le problème avec la mise en gras "Strong". Mais pour l'emphase je vois pas d'ou vient le problème.

Petit morceau de code pour tester :
<?php
	require_once 'Creole.class.php';
	
	$creoleParser = new CreoleParser();
	
	$txt = "=What's a Plouk=";
	$txt .= "{{http://www.ecoledesmax.com/espace_regroupeurs/pages_activites/documents/plouk.jpg|Un plouk}}\n\n";
	$txt .= "//Un plouk, un vrai//\n";
	$txt .= "==Un plouk en details==";
	$txt .= "Visitez : http://www.plouktv.com\n";
	$txt .= "**//http://www.google.fr//**\n";
	$txt .= "[[http://www.google.fr|Plouk library]]";

	echo $creoleParser->parse(nl2br($txt));
?>
Ma question étant comment éviter ces conflits ? Car si je modifie une règle, une autre rentre en conflit etc... Ca devient vite très compliqué. Es-ce qu'il faut modifier la règle entrant en conflit (ce que je n'arrive pas à vraiment faire), ou bien adapter les autres règles en conséquence ?
Es-ce que un parseur correctement fait peut tenir compte de l'ordre des règles parsées ou cela ne devrait pas avoir d'importance ?

Merci.

Cordialement,
Laurent