Page 1 sur 2

Vérifier si un texte repésente une valeur décimale ou hexa

Publié : lun. 20/févr./2012 22:15
par Le Soldat Inconnu
Un petit code qui permet de vérifier si un texte représente une valeur décimale ou une valeur hexadécimale

Code : Tout sélectionner

Procedure IsVal(Chaine.s)
	; Retourne différent de 0 si la chaine est un nombre
	Static Separateur.s
	Protected Verification.s
	If Separateur = ""
		Separateur = Mid(StrF(1.5), 2, 1)
		Debug Separateur
	EndIf
	Verification = StrD(ValD(Chaine))
	If FindString(Verification, Separateur)
		Verification = RTrim(RTrim(Verification, "0"), Separateur)
	EndIf
	Verification = RSet(Verification, Len(Chaine), "0")
	Debug Verification
	Debug Chaine
	If Verification = Chaine And Chaine
		Debug "Ok"
		ProcedureReturn 1
	Else
		Debug "Erreur"
		ProcedureReturn 0
	EndIf
EndProcedure

Procedure IsHexVal(Chaine.s)
	; Retourne différent de 0 si la chaine est une valeur hexadécimale
	Protected Verification.s
	Verification = Hex(Val(Chaine), #PB_Long)
	Verification = LTrim(Verification, "0")
	Verification = RSet(Verification, Len(Chaine) - 1, "0")
	Verification = "$" + Verification
	Debug Verification
	Debug Chaine
	If LCase(Verification) = LCase(Chaine) And Chaine
		Debug "Ok"
		ProcedureReturn 1
	Else
		Debug "Erreur"
		ProcedureReturn 0
	EndIf
EndProcedure

IsVal("12")
IsVal("-1052")
IsVal("1.25456")
IsVal("0")
IsVal("00123")
IsVal("100")
IsVal("bonjour")
IsVal("10 bonjour")
IsVal("a198")
IsVal("0011_")
IsVal("")

Debug ""
Debug "***************************"
Debug ""

IsHexVal("bonjour")
IsHexVal("10 bonjour")
IsHexVal("541")
IsHexVal("$0011_")
IsHexVal("$A198")

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : lun. 20/févr./2012 22:39
par Le Soldat Inconnu
Il y a bug, je corrige et je reposte

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : lun. 20/févr./2012 22:50
par Le Soldat Inconnu
bon, cela semble être mieux. Si vous avez des idées de valeur bizarre à tester, merci par avance pour vérifier la robustesse du code :D

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 19:22
par lepiaf31
Heu et avec un expression régulière c'est pas plus simple ? (et plus robuste du coup ^^) :

Code : Tout sélectionner

Procedure isVal(string.s)
  Protected res.b, regExp.i
  
  regExp = CreateRegularExpression(#PB_Any, "^-?[0-9]+(.[0-9]+)?$")
  res = MatchRegularExpression(regExp, string)
  FreeRegularExpression(regExp)
  
  ProcedureReturn res
EndProcedure

Procedure isHexVal(string.s)
  Protected res.b, regExp.i
  
  regExp = CreateRegularExpression(#PB_Any, "^-?\$[0-9A-Fa-f]+$")
  res = MatchRegularExpression(regExp, string)
  FreeRegularExpression(regExp)
  
  ProcedureReturn res
EndProcedure

Debug IsVal("12")
Debug IsVal("-1052")
Debug IsVal("1.25456")
Debug IsVal("0")
Debug IsVal("00123")
Debug IsVal("100")
Debug IsVal("bonjour")
Debug IsVal("10 bonjour")
Debug IsVal("a198")
Debug IsVal("0011_")
Debug "**************"
Debug IsHexVal("bonjour")
Debug IsHexVal("10 bonjour")
Debug IsHexVal("541")
Debug IsHexVal("$0011_")
Debug IsHexVal("$A198")

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 20:15
par Guimauve
Bonjour à tous,

@lepiaf31

C'est certain qu'avec les expressions régulières c'est plus simple. Cependant la valeur "0" n'est pas reconnue comme une valeur numérique alors que c'est le cas.

Code : Tout sélectionner

Procedure IsVal(string.s)
  
  Protected res.b, regExp.i
  
  regExp = CreateRegularExpression(#PB_Any, "^-?[0-9]+.[0-9]+$")
  res = MatchRegularExpression(regExp, string)
  FreeRegularExpression(regExp)
  
  ProcedureReturn res
EndProcedure

Procedure IsHexVal(string.s)
  
  Protected res.b, regExp.i
  
  regExp = CreateRegularExpression(#PB_Any, "^-?\$[0-9A-Za-z]+$")
  res = MatchRegularExpression(regExp, string)
  FreeRegularExpression(regExp)
  
  ProcedureReturn res
EndProcedure

Macro AddElementEx(ListName, Value)
  
  AddElement(ListName)
  ListName = Value
  
EndMacro

NewList Values.s()
NewList HexValues.s()

AddElementEx(Values(), "12")
AddElementEx(Values(), "-1052")
AddElementEx(Values(), "1.25456")
AddElementEx(Values(), "0")
AddElementEx(Values(), "000123")
AddElementEx(Values(), "100")
AddElementEx(Values(), "bonjour")
AddElementEx(Values(), "10 bonjour")
AddElementEx(Values(), "a198")
AddElementEx(Values(), "0011_")

AddElementEx(HexValues(), "bonjour")
AddElementEx(HexValues(), "10 bonjour")
AddElementEx(HexValues(), "541")
AddElementEx(HexValues(), "$0011_")
AddElementEx(HexValues(), "$A198")

ForEach Values()
  
  If IsVal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur numérique"
  Else
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " n'est pas une valeur numérique"
  EndIf
  
Next

Debug ""
Debug "**************"
Debug ""

ForEach HexValues()
  
  If IsHexVal(HexValues()) = 1
    Debug "L'entrée " + Chr(34) + HexValues() + Chr(34) + " est bien une valeur hexadécimale"
  Else
    Debug "L'entrée " + Chr(34) + HexValues() + Chr(34) + " n'est pas une valeur hexadécimale"
  EndIf
  
Next
Débogueur a écrit :L'entrée "12" n'est pas une valeur numérique
L'entrée "-1052" est bien une valeur numérique
L'entrée "1.25456" est bien une valeur numérique
L'entrée "0" n'est pas une valeur numérique
L'entrée "000123" est bien une valeur numérique
L'entrée "100" est bien une valeur numérique
L'entrée "bonjour" n'est pas une valeur numérique
L'entrée "10 bonjour" n'est pas une valeur numérique
L'entrée "a198" n'est pas une valeur numérique
L'entrée "0011_" n'est pas une valeur numérique

**************

L'entrée "bonjour" n'est pas une valeur hexadécimale
L'entrée "10 bonjour" n'est pas une valeur hexadécimale
L'entrée "541" n'est pas une valeur hexadécimale
L'entrée "$0011_" n'est pas une valeur hexadécimale
L'entrée "$A198" est bien une valeur hexadécimale
De plus, je pense qu'il faudrait ajouter un commande de type IsRealVal() pour les nombres réels (Float et Double)

A+
Guimauve

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 20:19
par lepiaf31
Ooooups en effet, petite erreur dans l'expression. Code corrigé, maintenant ca marche ;)

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 20:44
par Guimauve
Il y a encore un problème, les valeurs hexadécimales s'arrête à F ou f. Voici une version corrigé. IsVal() s'occupe des valeurs entières seulement, IsReal() s'occupe des valeurs numériques plus générale et finalement IsHexVal() s'occupe des valeur kexadécimales.

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Commande dé vérification du type de valeur
; Nom du fichier : IsVal - IsReal - IsHexVal.pb
; Version du fichier : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 21-02-2012
; Mise à jour : 21-02-2012
; Code PureBasic : 4.50
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure IsVal(string.s) 
  
  Protected res.b, regExp.i 

  regExp = CreateRegularExpression(#PB_Any, "^-?[0-9]+?$")
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

Procedure IsHexVal(string.s) 
  
  Protected res.b, regExp.i 
  
  regExp = CreateRegularExpression(#PB_Any, "^-?\$[0-9A-Fa-f]+$") 
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

Procedure IsReal(string.s) 
  
  Protected res.b, regExp.i 
  
  regExp = CreateRegularExpression(#PB_Any, "^-?[0-9]+(.[0-9]+)?$") 
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< !!! ATTENTION - CODE D'ESSAI !!! <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Macro AddElementEx(ListName, Value)
  
  AddElement(ListName)
  ListName = Value
  
EndMacro

NewList Values.s()

AddElementEx(Values(), "12")
AddElementEx(Values(), "-1052")
AddElementEx(Values(), "1.25456")
AddElementEx(Values(), "0")
AddElementEx(Values(), "0.0")
AddElementEx(Values(), "000123")
AddElementEx(Values(), "100")
AddElementEx(Values(), "bonjour")
AddElementEx(Values(), StrD(2.0*#PI, 18))
AddElementEx(Values(), "10 bonjour")
AddElementEx(Values(), "a198")
AddElementEx(Values(), "0011_")

AddElementEx(Values(), "bonjour")
AddElementEx(Values(), "100 bonjour")
AddElementEx(Values(), "541")
AddElementEx(Values(), "$0011_")
AddElementEx(Values(), "$A198")
AddElementEx(Values(), "$Z198")

ForEach Values()
  
  If IsVal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur numérique entière"
  ElseIf IsReal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur numérique flottante"
  ElseIf IsHexVal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur hexadécimale"
  Else
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " n'est pas une valeur valide"
  EndIf

Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
A+
Guimauve

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 21:08
par lepiaf31
Oula oui, tu as raison !!

Décidemment, c'est pas la grande forme ce soir ..

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 21:19
par Guimauve
Re-Bonjour,

Je pense que pour être plus "Safe" il faudrait faire comme suit :

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Commande dé vérification du type de valeur
; Nom du fichier : IsVal - IsReal - IsHexVal.pb
; Version du fichier : 1.0.1
; Programmation : OK
; Programmé par : Guimauve
; Date : 21-02-2012
; Mise à jour : 21-02-2012
; Code PureBasic : 4.50
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Note :
;
; Les commandes suivantes sont inspirés d'un code fournie par 
; lepiaf (forum PureBasic Fr)
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure IsVal(string.s) 
  
  Protected res.b, regExp.i 

  regExp = CreateRegularExpression(#PB_Any, "^[-+]?[0-9]+?$")
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

Procedure IsHexVal(string.s) 
  
  Protected res.b, regExp.i 
  
  regExp = CreateRegularExpression(#PB_Any, "^[-+]?\$[0-9A-Fa-f]+$") 
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

Procedure IsReal(string.s) 
  
  Protected res.b, regExp.i 
  
  regExp = CreateRegularExpression(#PB_Any,"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$")
  res = MatchRegularExpression(regExp, string) 
  FreeRegularExpression(regExp) 
  
  ProcedureReturn res 
EndProcedure 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< !!! ATTENTION - CODE D'ESSAI !!! <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Macro AddElementEx(ListName, Value)
  
  AddElement(ListName)
  ListName = Value
  
EndMacro

NewList Values.s()

AddElementEx(Values(), "12")
AddElementEx(Values(), "-1052")
AddElementEx(Values(), "1.25456")
AddElementEx(Values(), "0")
AddElementEx(Values(), "0.0")
AddElementEx(Values(), "000123")
AddElementEx(Values(), "100")
AddElementEx(Values(), "bonjour")
AddElementEx(Values(), StrD(2.0*#PI, 18))
AddElementEx(Values(), "10 bonjour")
AddElementEx(Values(), "1.5e25")
AddElementEx(Values(), "a198")
AddElementEx(Values(), "0011_")
AddElementEx(Values(), "bonjour")
AddElementEx(Values(), "100 bonjour")
AddElementEx(Values(), "541")
AddElementEx(Values(), "$0011_")
AddElementEx(Values(), "$A198")
AddElementEx(Values(), "$Z198")

ForEach Values()
  
  If IsVal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur numérique entière"
    Found = 1
  EndIf
  
  If IsReal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur numérique flottante"
    Found = 1
  EndIf
  
  If IsHexVal(Values()) = 1
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " est bien une valeur hexadécimale"
    Found = 1
  EndIf
  
  If Found = 1
    Found = 0
  Else
    Debug "L'entrée " + Chr(34) + Values() + Chr(34) + " n'est pas une valeur valide"
  EndIf
  
  Debug ""
  
Next

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
L'ennui c'est que la commande IsReal() prend les valeurs entières comme valide. Je n suis pas sûr que ce problème puisse être corrigé. La meilleure solution serait probablement de procéder en deux étapes, la première à savoir si c'est une valeur numérique générale et la 2e à savoir s'il s'agit d'une valeur entière ou d'un réel.

A+
Guimauve

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 21:32
par lepiaf31
Il ne suffit pas juste d'enlever ce point d'interrogation: ^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$

Le point deviendra alors obligatoire dans l'expression et on aura donc forcément un nombre flottant.

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mar. 21/févr./2012 23:18
par Guimauve
Je ne sais pas trop comment fonctionne les expressions régulières en fait. Je me suis basé sur un exemple disponible ici : http://www.regular-expressions.info/floatingpoint.html

Seulement si le point devient obligatoire et que l'on tente de lire un fichier WaveFrontObject et que le logiciel qui à générer le fichier ne met par les valeurs du genre "0.000000", il met "0" ça va poser de graves problèmes.
La meilleure solution est celle qui sera adapté au contexte du problème à solutionner.

A+
Guimauve

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mer. 22/févr./2012 0:31
par Le Soldat Inconnu
sauf que le séparateur peut être une virgule, cela dépend des options régionale en fait (quel bordel ce truc)

J'ai modifié mon premier code par rapport à cela.

Les expressions régulières, ce n'est pas trop lent ?
Il faut que je compare les temps de traitement.

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mer. 22/févr./2012 0:41
par Le Soldat Inconnu
Ma méthode est presque 1.5 fois plus rapide chez moi, et pour vous ? (je n'ai comparer que pour les réels)

Code : Tout sélectionner

Procedure IsVal(Chaine.s)
	; Retourne différent de 0 si la chaine est un nombre
	Static Separateur.s
	Protected Verification.s
	If Separateur = ""
		Separateur = Mid(StrF(1.5), 2, 1)
		Debug Separateur
	EndIf
	Verification = StrD(ValD(Chaine))
	If FindString(Verification, Separateur)
		Verification = RTrim(RTrim(Verification, "0"), Separateur)
	EndIf
	Verification = RSet(Verification, Len(Chaine), "0")
	Debug Verification
	Debug Chaine
	If Verification = Chaine And Chaine
		Debug "Ok"
		ProcedureReturn 1
	Else
		Debug "Erreur"
		ProcedureReturn 0
	EndIf
EndProcedure


Procedure IsReal(string.s)  
	
	Protected res.b, regExp.i  
	
	regExp = CreateRegularExpression(#PB_Any,"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$") 
	res = MatchRegularExpression(regExp, string)  
	FreeRegularExpression(regExp)  
	
	ProcedureReturn res  
EndProcedure 


#nb = 500000

Temps1 = ElapsedMilliseconds()

For n = 1 To #nb
	IsVal("123.45") 
Next

Temps2 = ElapsedMilliseconds()

For n = 1 To #nb
	IsReal("123.45") 
Next

Temps3 = ElapsedMilliseconds()

MessageRequester("Test rapidité", "Solution 1 : " + Str(Temps2 - Temps1) + " ; Solution 2 : " + Str(Temps3 - Temps2) + Chr(10) + "Ratio = 1 / " + StrF((Temps2 - Temps1) / (Temps3 - Temps2)), 0)

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mer. 22/févr./2012 1:21
par Guimauve
Bonjour,

Moi le résultat qui s'affiche c'est :
  • Solution 1: 600
  • Solution 2 : 848
  • Ratio = 1 / 0.70754718
Un peu plus lent effectivement.

LinuxMint 12 x64 + PureBasic 4.61 Beta 1 x64

A+
Guimauve

Re: Vérifier si un texte repésente une valeur décimale ou he

Publié : mer. 22/févr./2012 8:43
par PAPIPP
Bonjour à tous
il n'est pas nécessaire de libérer et de recréer l’expression régulière à chaque appel ce qui nous fait gagner un peu de temps.

Code : Tout sélectionner

Procedure IsVal(Chaine.s)
  ; Retourne différent de 0 si la chaine est un nombre
  Static Separateur.s
  Protected Verification.s
  If Separateur=""
    Separateur=Mid(StrF(1.5),2,1)
    Debug Separateur
  EndIf
  Verification=StrD(ValD(Chaine))
  If FindString(Verification,Separateur)
    Verification=RTrim(RTrim(Verification,"0"),Separateur)
  EndIf
  Verification=RSet(Verification,Len(Chaine),"0")
  Debug Verification
  Debug Chaine
  If Verification=Chaine And Chaine
    Debug "Ok"
    ProcedureReturn 1
  Else
    Debug "Erreur"
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure IsReal(string.s)
  Static flag.i,res.b,regExp.i
  If flag=0
    regExp=CreateRegularExpression(#PB_Any,"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$")
    flag=1
  EndIf
  res=MatchRegularExpression(regExp,string)
;   FreeRegularExpression(regExp)
  
  ProcedureReturn res
EndProcedure


#nb=500000

Temps1=ElapsedMilliseconds()

For n=1 To #nb
  IsVal("123.45")
Next

Temps2=ElapsedMilliseconds()

For n=1 To #nb
  IsReal("123.45")
Next

Temps3=ElapsedMilliseconds()

MessageRequester("Test rapidité","Solution 1 : "+Str(Temps2-Temps1)+" ; Solution 2 : "+Str(Temps3-Temps2)+Chr(10)+"Ratio = 1 / "+StrF((Temps2-Temps1)/(Temps3-Temps2)),0)

@+