Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 01/09/2007, 14h44   #1
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
Par défaut Détection d'anti-slash

Je souhaite traiter des chemins de fichiers.. j'ai trouvé un comportement qui me semble anormal dès qu'il y a certains chiffres après. Qui peut m'expliquer ou se trouve mon erreur dans mon tout petit motif de détection d'antislash ('[\\\]') ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
	//$str_chaine_avec_antislash="abcde\fghij.php"; // renvoi "found"
	//$str_chaine_avec_antislash="abcde\ fghij.php"; // renvoi "found"
	//$str_chaine_avec_antislash="abcde\0fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\1fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\2fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\3fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\4fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\5fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\6fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\7fghij.php"; // renvoi "NOT found"
	//$str_chaine_avec_antislash="abcde\8fghij.php"; // renvoi "found"
	//$str_chaine_avec_antislash="abcde\9fghij.php"; // renvoi "found"
	//--- tester si présence d'un antislash dans la chaine
	if(preg_match('[\\\]',$str_chaine_avec_antislash)==1) echo "\n found \n";
	else echo "\n NOT found \n";
Merci aux posteurs éclairés et bienveillants qui pourront m'aider.
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 15h51   #2
Membre expérimenté
 
Inscription : septembre 2006
Messages : 685
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 685
Points : 564
Points : 564
Je suppose que c'est parce qu'un antislash suivit d'un nombre désigne une référence arrière.

En utilisant preg_quote() sur la chaine à analyser le problème est règlé.
Xunil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 15h58   #3
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
Merci Xunil, ça marche... presque :

si j'essaye avec une chaine sans le point :

Code :
	$str_chaine_avec_antislash="abcde\2fghijphp"; // renvoi "not found"
il ne trouve pas mon antislash...

... en + continuant mon code, j'ai trouvé des effets bizzares (pour la première fois j'ai un code qui me nargue littéralement en m'envoyant un smiley - voir les post suivant)
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 16h50   #4
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
Maintenant je veux remplacer l'antislash par un point... ça devrait être facile...
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
	//$str_chaine_avec_antislash="abcde\fghij.php"; // renvoi "found"
	//$str_chaine_avec_antislash="abcde\ fghij.php"; // renvoi "found"
	$str_chaine_avec_antislash="abcde\2fghij.php"; // renvoi "found"
	//--- tester si présence d'un antislash dans la chaine
	find_and_replace_antislash($str_chaine_avec_antislash);
 
	function find_and_replace_antislash($str_to_detect)
	{
	if(preg_match('[\\\]',preg_quote($str_to_detect))==1) echo "\n found \n";
	else echo "\n NOT found \n";
	echo preg_replace('[\\\]',".",preg_quote($str_to_detect));
	}
facile ?... Résultat pour le code au-dessus :

Citation:
found
abcdefghij..php // j'ai mis un smiley, car sous dos ça me donne vraiment ça (mais en version monochrome)

Résumé de mes galères : preg_match trouve bien mon antislash.. mais :
  • preg_quote me double les points
  • preg_replace m'a transformé mon antislash en "" (c'est joli mais bon..)
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 17h21   #5
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
En fait, il semble que :

preg_match('[\\\]',preg_quote($str_to_detect));

ne soit pas équivalent en terme de détection que

preg_replace('[\\\]',......,preg_quote($str_to_detect));

puisque ce dernier parvient pas a remplacer l'antislash détecté pourtant par le précedent preg_match...

SAUF que si j'active les options de preg_replace pour lire le nombre de remplacement :

Code :
1
2
3
4
5
6
7
8
9
10
11
	$str_chaine_avec_antislash="abcde\2fghij.php"; // renvoi "found"
	//--- tester si présence d'un antislash dans la chaine
	find_and_replace_antislash($str_chaine_avec_antislash);
	//'[\\\]'
	function find_and_replace_antislash($str_to_detect)
	{
	if(preg_match('[\\\]',preg_quote($str_to_detect))==1) echo "\n found \n";
	else echo "\n NOT found \n";
	echo preg_replace('[\\\]',".",preg_quote($str_to_detect),-1,$nb_remplacement);
	echo " \n nb de remplacement antislashe  : ".$nb_remplacement;
	}
j'ai la même réponse (smiley + le double point) avec en plus :
Citation:
nb de remplacement antislashe : 1
En clair : preg_replace détecte bien l'anti-slash, mais place le caractère de remplacement au mauvais endroit ! (juste avant ..ou après le point de la fin de la chaine originale ".php")

Bug de preg_replace ???
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 19h24   #6
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
En fait Xinul, je pense que preg_quote n'est pas la solution, car si je fait le test suivant (sans preg_quote) :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
	$str_chaine_avec_antislash="abcde\2fghijphp"; // renvoi "not found"
	find_and_replace_antislash($str_chaine_avec_antislash);
	$str_chaine_avec_antislash="abcde\\2fghijphp"; // renvoi "found" + remplacement ok
	find_and_replace_antislash($str_chaine_avec_antislash);
	//***** function *****
	function find_and_replace_antislash($str_to_detect)
	{
	if(preg_match('[\\\]',$str_to_detect)==1) echo "\n found \n";
	else echo "\n NOT found \n";
	echo preg_replace('[\\\]','.',$str_to_detect,-1,$nb_remplacement);
	echo " \n nb de remplacement antislashe  : ".$nb_remplacement;
	}
J'ai (avec un smiley monochrome) :


Citation:
NOT found
abcdefghijphp
nb de remplacement antislashe : 0
found
abcde.2fghijphp
nb de remplacement antislashe : 1
En fait il semble qu'il faudrait trouver l'équivalent de addslashe.. pour les antislash (addbackslashes ?) et faire :

Code :
1
2
3
 
	$str_chaine_avec_antislash="abcde\2fghijphp"; 
	$str_chaine_avec_antislash=addbackslashes ($str_chaine_avec_antislash);
Avec tout les pb de manipulation des antislash regex que j'ai déjà.. je sens que developper addbackslashes va etre simple...

Le premier qui me dit que les regex font gagner du temps...:
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 20h02   #7
Membre expérimenté
 
Inscription : septembre 2006
Messages : 685
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 685
Points : 564
Points : 564
En fait, non preg_quote() n'est pas utile

Tes résultats sont faussés car tes chaines sont entre guillemets, donc évaluées par php.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$str_chaine_avec_antislash[]='abcde\2fghijphp';
$str_chaine_avec_antislash[]='abcde\fghij.php';
$str_chaine_avec_antislash[]='abcde\\fghij.php';
$str_chaine_avec_antislash[]='abcde\0fghij.php';
$str_chaine_avec_antislash[]='abcde\1fghij.php';
$str_chaine_avec_antislash[]='abcde\2fghij.php';
$str_chaine_avec_antislash[]='abcde\3fghij.php';
$str_chaine_avec_antislash[]='abcde\4fghij.php';
$str_chaine_avec_antislash[]='abcde\5fghij.php';
$str_chaine_avec_antislash[]='abcde\6fghij.php';
$str_chaine_avec_antislash[]='abcde\7fghij.php';
$str_chaine_avec_antislash[]='abcde\8fghij.php';
$str_chaine_avec_antislash[]='abcde\9fghij.php';
//--- tester si présence d'un antislash dans la chaine
foreach( $str_chaine_avec_antislash as $val )
{
	echo $val . ' --> ';
	if( preg_match('#\\\#', $val) ) echo "\n found \n";
	else echo "\n NOT found \n";
	echo '<br>';
}
Donne bien found pour tous les éléments.

Mais si c'est pour détecter qu'un \ est présent dans ta chaine, strpos() est amplement suffisant.
Xunil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/09/2007, 21h45   #8
Membre régulier
 
Inscription : mai 2007
Messages : 180
Détails du profil
Informations forums :
Inscription : mai 2007
Messages : 180
Points : 82
Points : 82
Très interessant.

Merci beaucoup Xunil, j'avais pas capté l'erreur.

Voila donc maintenant un bon bout de code bien bétonné avec le bon controle d'erreur "qui va bien", du bon code robuste comme le faisait nos grand-parents dans l'ancien temps :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
	//****** test with bad double-quote parameter
	test_replace_backslash("abcde\2fghijphp",".");
	//******
	echo "\n";
	//****** test with good simple quote parameter
	test_replace_backslash('abcde\2fghijphp',".");
	//**************************************
 
	//***** function *****
	function test_replace_backslash($str_test,$str_replace)
	{
		$str_new= replace_backslash($str_test,".");
		if (!$str_new) echo "no readable char found - control call with 'string' and not ".'"'."string".'"';
		else echo $str_new;
	}
	//***** 
	function replace_backslash($str_to_detect,$str_replace)
	{
		if(chrs_is_all_readable($str_to_detect)) {
			return(preg_replace('[\\\]',$str_replace,$str_to_detect));
		}
		return (false);
	}
	//***** 
	function chrs_is_all_readable($string)
	{
	  for ($i=0;$i<strlen($string);$i++)
		{
			$chr = $string{$i};
			$ord = ord($chr);
			if ($ord<32 or $ord>126) return(false);
		}
	  return (true);
	}
ce qui nous retourne :

Code :
1
2
3
 
no readable char found - control call with 'string' and not "string"
abcde.2fghijphp
gomodo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h04.


 
 
 
 
Partenaires

Hébergement Web