Script correcteur de ponctuation

Contenu du snippet

Bonjour à tous,

voici une fonction à base de regex qui permet de corriger la syntaxe de ponctuation d'un texte sans toucher aux URLs ni adresses email qu'il peut contenir.

J'espère que ça servira à quelqu'un, en tout cas j'en avais bien besoin et ai passé un certain temps dessus.

Si quelqu'un trouve une faille ou une optimisation du code, qu'il n'hésite pas à apporter sa contribution !

Source / Exemple :


function corrige_ponctuation($string) {

	function corrige($substring) {
			
		$tab1 = array(
		'` +`',//supprimer les espaces multiples
		'`(\w)(:|;|\?|!)`',//autre ponctuation : espace avant et après
		'`(\?|!)\s*(["\)])`',//autre ponctuation : pas d'espace après si suivi d'un guillemet ou parenthèse fermante
		'`"\s*([^"]+)\s*"`',//guillemets : espace avant et après mais pas à l'intérieur
		'`"\s*([^"]+)\s*"([\.,\)])`',//guillemets : idem mais pas d'espace après si suivi de point, virgule ou parenthèse fermante
		'`\(\s*([^\)]+)\s*\)`',//parenthèses : espace avant et après mais pas à l'intérieur
		'`\(\s*([^\)]+)\s*\)([\.\),"])`',//parenthèses : idem mais pas d'espace après si suivies de point, virgule, parenthèse fermante ou guillemet
		'`\s*(\.|,)([^\.])`',//point et virgule : espace après, pas avant sauf si suivi d'un point
		'`(\d)\s*(\.|,)\s*(\d)`',//point et virgule : si on a affaire à un nombre décimal on ne touche rien
		'`\s*\'\s*`',//apostrophes : pas d'espace avant ni après
		'`([!\?\."])\s+([!\?\.])`');//supprimer les espaces entre point, point d'interrogation ou d'exclamation (ex : ? !! devient ?!!) et entre l'apostrophe et un point quelconque
		
		$tab2 = array(
		' ',//espaces multiples
		'$1 $2',//autre ponctuation
		' $1$2',//autre ponctuation 2ème partie
		' "$1" ',//guillemets
		' "$1"$2',//guillemets 2ème partie
		' ($1) ',//parenthèses
		' ($1)$2',//parenthèses 2ème partie
		'$1 $2',//point et virgule
		'$1$2$3',//point et virgule
		'\'',//apostrophes
		'$1$2');//supprimer les espaces entre caractères de ponctuation
		
		$substring = preg_replace($tab1,$tab2,$substring);
		
		$substring = preg_replace("/(\.|\?|!)(\s+)(\w)/e",'strtoupper("$1$2$3")',$substring);//mettre en majuscule après certains caractères
		
		return $substring;
	}
	
	$masque_url = '((https?|ftp)://(w{3}\.)?)(?<!www)(\w+-?)*\.([a-z]{2,4})';
	$masque_email = ':alnum:([-_.]?:alnum:)*@:alnum:([-_.]?:alnum:)*\.([a-z]{2,4})';
	
	if (preg_match_all('`'.$masque_url.'|'.$masque_email.'`', $string, $matches, PREG_PATTERN_ORDER))//s'il y a une adresse web ou mail dans le texte à corriger
	{
		$portion = corrige(substr($string,0,strpos($string,$matches[0][0])));//première portion de texte à corriger avant le premier masque rencontré
		if (count($matches[0])>1)
		{
			for ($i=1;$i<count($matches[0]);$i++)//on va découper les portions de texte à corriger qui ne matchent pas les masques et les masques
			{
				$portion.= $matches[0][$i-1];//masque suivant
				$portion.= corrige(substr($string,strpos($string,$matches[0][$i-1]) + strlen($matches[0][$i-1]),strpos($string,$matches[0][$i]) - (strpos($string,$matches[0][$i-1]) + strlen($matches[0][$i-1]))));//portion de texte entre deux masques web ou email
			}
		}
		$portion.= $matches[0][count($matches[0])-1];//dernier masque
		$portion.= corrige(substr($string,strpos($string,$matches[0][count($matches[0])-1]) + strlen($matches[0][count($matches[0])-1])));//dernière portion de texte à corriger
		return $portion;
	}
	else
	{
		return corrige($string);
	}
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.