Caractère non pris en charge par l'EDI

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
gibet_b
Messages : 13
Inscription : lun. 03/déc./2012 18:15
Localisation : Au coeur des Combrailles (63)
Contact :

Caractère non pris en charge par l'EDI

Message par gibet_b »

Bonjour à tous,

Comme je l'ai dit dans un autre sujet, je me frotte à PureBasic, en transposant une petite application que j'ai créé pour aider ma femme à faire des textes à trous.

Je parcours le texte soumis caractère par caractère, et pour détecter s'il s'agit d'un caractère de ponctuation, voilà comment je faisais sous RealBasic :

1/ Je déclarais une constante contenant tous les signes de ponctuation (ou en tout cas ceux qui m'intéressent) :

Code : Tout sélectionner

Const PONCTUATION = ".,;?!()"“”«»':-—–’"
2/ Je vérifiais si le caractère en cours figurait dans la contante pour savoir si c'était un signe de ponctuation :

Code : Tout sélectionner

If InStrB(PONCTUATION,caractere) > 0
Le hic, c'est que certains caractère sont remplacés par des "?" lorsque je copie/colle dans l'EDI de RealBasic. Notamment, une des deux formes d'apostrophe( ’ ), mais aussi les différents tirets ( — et – ) et certaines formes de guillemets( “” ).

Du coup, je me demandais si vous aviez un bout de code élégant pour détecter s'il s'agit d'un signe de ponctuation ? Ou faut-il que je compare grâce aux valeurs ascii (ça demande beaucoup plus de code pour la même chose) ?
Jean-Baptiste,
Développement logiciel, infographie, livres numériques et sites internet en Auvergne : www.bournisien.info
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par falsam »

Les expressions régulières devraient t'aider à répondre à ta question.

CreateRegularExpression() pour créer l'expression régulière.
MatchRegularExpression() pour vérifier que la chaîne traitée contient bien l'expression régulière créée précédemment.

Exemple de création d'expression réguliére pour tester qu'une chaine contient bien des chiffres de 0 à 9.
Les crochets [] définissent la liste de caractères autorisés.

Code : Tout sélectionner

*RegMatch = CreateRegularExpression(#PB_Any ,"[0-9]") 
Le code ci-dessous retournera #True

Code : Tout sélectionner

debug MatchRegularExpression (*RegMatch, "123")
le code ci-dessous retournera #False

Code : Tout sélectionner

Debug MatchRegularExpression (*RegMatch, "Pure Basic")
Encore un exemple pour tester des balises h1 à h6 dans une chaîne html

Code : Tout sélectionner

*RegMatch = CreateRegularExpression(#PB_Any ,"<h[1-6]>")
Debug MatchRegularExpression (*RegMatch, "<h1>Une balise de titre HTML</h1>")
Revenons à ta demande. Il existe une classe pour tester les ponctuations.

Code : Tout sélectionner

*RegMatch = CreateRegularExpression(#PB_Any ,"[[:punct:]]")
Buffer$="Une phrase ponctuée par des , des ."
Debug MatchRegularExpression (*RegMatch, Buffer$)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Caractère non pris en charge par l'EDI

Message par graph100 »

si tu veux aller un peu plus loin avec les regex :

Code : Tout sélectionner

;{ LIB code

; AIDE à :
; http://www.lumadis.be/regex/test_regex.php

ImportC ""
	pb_pcre_exec(*pcre,*extra,subject.s,length,startoffset,options,*ovector,ovecsize)
EndImport


Structure List_Extraction
	Array Extract.s(0)
EndStructure


Procedure.s BackrefReplaceRegularExpression(regexp_handle, string.s, replacement.s, maximum_reference.l = 10) ; 0 <= maximum_reference <= 99
	Static Dim pcre_results(202)
	
	Protected depart.l, char$, rpl.s, tableau_ref.l, tag$, p1.l, q1.l
	
	depart = 0
	
	While pb_pcre_exec(PeekL(regexp_handle), 0, string, Len(string), depart, 0, @pcre_results(), 202) > 0
		; pcre_exec(PeekL(regexp_handle), 0, string, Len(string), pcre_results(1), 0, @pcre_results(), 202)
		
		rpl.s = replacement
		
		p = pcre_results(0)
		q = pcre_results(1)
		If FindString(replacement,"$0", 1)
			rpl = ReplaceString(rpl, "$0", PeekS(@string + p, q - p))
			
		EndIf
		
		tableau_ref = 2
		
		For _a = 1 To maximum_reference
			tag$ = "$" + Str(_a)
			
			If FindString(replacement, tag$, 1)
				p1 = pcre_results(tableau_ref)
				q1 = pcre_results(tableau_ref + 1)
				rpl = ReplaceString(rpl, tag$, PeekS(@string + p1, q1 - p1))
				
			EndIf
			
			tag$ = "$#" + Str(_a)
			
			position.l = FindString(replacement, tag$, 1)
			If position
				char$ = Mid(replacement, position+Len(tag$), 1)
				
				p1 = pcre_results(tableau_ref)
				q1 = pcre_results(tableau_ref + 1)
				rpl = ReplaceString(rpl, tag$, RSet("",Len(PeekS(@string + p1, q1 - p1)),char$))
				
			EndIf
			
			tableau_ref + 2
		Next
		
		depart = p + Len(rpl)
		
		string = Left(string, p) + rpl + Right(string, Len(string) - q)
	Wend
	
	ProcedureReturn string
EndProcedure

Procedure.s BackrefExtractRegularExpression(regexp_handle, string.s, Array Extract.b(1), List Resultat.List_Extraction()) ; 0 <= Taille tableau Extract <= 99
	Static Dim pcre_results(202)
	
	depart = 0
	
	maximum_reference = ArraySize(Extract())
	
	ClearList(Resultat())
	
	While pb_pcre_exec(PeekL(regexp_handle), 0, string, Len(string), depart, 0, @pcre_results(), 202) > 0
		; pcre_exec(PeekL(regexp_handle), 0, string, Len(string), pcre_results(1), 0, @pcre_results(), 202)
		
		AddElement(Resultat())
		Dim Resultat()\Extract(maximum_reference)
		
		p = pcre_results(0)
		q = pcre_results(1)
		If Extract(0) = #True
			Resultat()\Extract(0) = PeekS(@string + p, q - p)
		EndIf
		
		tableau_ref = 2
		
		For _a = 1 To maximum_reference
			
			If Extract(_a) = #True
				p1 = pcre_results(tableau_ref)
				q1 = pcre_results(tableau_ref + 1)
				
				Resultat()\Extract(_a) = PeekS(@string + p1, q1 - p1)
			EndIf
			
			tableau_ref + 2
		Next
		
		depart = p ; + Len(rpl)
		
		string = Left(string, p) + Right(string, Len(string) - q)
	Wend
	
	ProcedureReturn string
EndProcedure


;}

; in punct : [\]\[!"#$%&'()*+,./:;<=>?@\^_`{|}~-]

; REGEX$ = "([[:punct:]])(.*?)([[:punct:]])"
REGEX$ = "([\("+Chr(34)+"“«<\[{-])(.*?)([\)"+Chr(34)+"”»>\]}-])"
rh = CreateRegularExpression(#PB_Any ,REGEX$)

CHAINE$ = "How To find "+Chr(34)+"the"+Chr(34)+" And "+Chr(34)+"these"+Chr(34)+" followed by a word (To capture) in the «following» text."


Debug "#### Recurrent Replacement test :"
Debug ""
Debug "Starting text :"
Debug CHAINE$
Debug "Regex = ||" + REGEX$ + "||"
Debug ""
Debug "Result :"
Debug BackrefReplaceRegularExpression(rh, CHAINE$, "_$0_")


; creation of the array specifying which parenthesis must be returned
Dim tableau_extraction.b(3)

; we want all parenthesis so we complete the array all the way
For a = 0 To 3
	tableau_extraction(a) = #True
Next


; creation of the list returning the result
NewList Result.List_Extraction()


; processing
BackrefExtractRegularExpression(rh, CHAINE$, tableau_extraction(), Result())

Debug ""
Debug ""
Debug "#### Recurrent extraction test :"
Debug ""
Debug "Starting text :"
Debug CHAINE$
Debug "Regex = ||" + REGEX$ + "||"
Debug ""
Debug "Extracted values :"
Debug ""

b = 0
ForEach Result()
	Debug "Occurrence " + Str(b)
	
	For a = 0 To 3
		Debug "$" + Str(a) + " = " + Result()\Extract(a)
	Next
	
	b + 1
Next

Debug ""
Debug "exemple dans lequel on remplace les mots entre ponctuation par autant de '_' qu'il y avait de lettres."
Debug ""
Debug BackrefReplaceRegularExpression(rh, CHAINE$, "$1$#2_$3", 3)
Il est possible de modifier BackrefReplaceRegularExpression() pour que le nombre de _ corresponde au nombre de lettre d'avant.
Tu peux utiliser le lien suivant pour tester des regex facilement : test_regex

J'en profite pour mentionner que les options de creation de regex sont un peu "pauvre", par exemple, on ne peux pas utilsier l'option U (ungreedy). Il faut la mentionner à chaque fois dans la regex.. C'est dommage.
Dernière modification par graph100 le dim. 09/déc./2012 0:19, modifié 2 fois.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
gibet_b
Messages : 13
Inscription : lun. 03/déc./2012 18:15
Localisation : Au coeur des Combrailles (63)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par gibet_b »

Merci 1000 fois à vous pour vos suggestions et vos nombreux exemples. Grâce à eux, je vais peut-être enfin trouver le courage de me mettre aux regex 8)

Je vous tiens au courant de mes aventures :)
Jean-Baptiste,
Développement logiciel, infographie, livres numériques et sites internet en Auvergne : www.bournisien.info
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Caractère non pris en charge par l'EDI

Message par graph100 »

J'ai modifié le code de mon post ci-dessus pour qu'il corresponde plus à ce que tu voulais faire.

La regex suivante : ([\("“«<\[{-])(.*?)([\)"”»>\]}-])
permet de capturer le caractère de ponctuation ouvrant, puis le texte à l'intérieur, et enfin le caractère fermant.
$0 correspond au texte qui match l'expression reg.
$1 est le premier caractère ouvrant, $2 le texte au milieu, $3 le caractère fermant.

Le problème de cette expression est que si les caractères ne sont pas correctement définis, il vont quand même fonctionner :
dans la phrase "suivante), la regex va capturer "suivante)... même si les caractères ne correspondent pas.
Enfin, c'est pas trop grave.

Tu peux aussi définir une regex pour ne capture le texte que si il n'y a qu'un seul mot entre les caractères de capture :

Code : Tout sélectionner

REGEX$ = "([\("+Chr(34)+"“«<\[{-])(\w*?)([\)"+Chr(34)+"”»>\]}-])"
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
wood51
Messages : 122
Inscription : ven. 05/juin/2009 13:04
Localisation : orléans

Caractère non pris en charge par l'EDI

Message par wood51 »

Gibet_b: pour les regex tu peut essayer le log gratuit RegexCoach c'est super pour tester c'est regex avant de les inclurent dans les codes . Moi qui suis une burne en regex je suis fan !!!

@+ wood51
Compétences : Bricoleur PureBasic du dimanche
Crâmage de cerveau en cours 100% :D
Projet en cours : http://purepicbasic.frenchboard.com/
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Caractère non pris en charge par l'EDI

Message par Ar-S »

Salut Gibet_b,
Je t'invite à parcourir et étudier ce topic. On y a mis pas mal d'exemples.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
gibet_b
Messages : 13
Inscription : lun. 03/déc./2012 18:15
Localisation : Au coeur des Combrailles (63)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par gibet_b »

Me revoilà pour chercher un peu d'éclaircissement sur les très obscurs expressions régulières 8)

Pour résoudre mon problème, je voulais tester si le code ascii "renvoyé" par :

Code : Tout sélectionner

MatchRegularExpression (*RegPonctuation, Str(Asc(caractere)))
était bien compris dans certaines plages, avec "l'expression régulière suivante" :

Code : Tout sélectionner

Define *RegPonctuation = CreateRegularExpression(#PB_Any ,"[33-47]|[91-93]|[123-125]|130|[132-133]|[145-151]|171|180|187")
Mais visiblement, ce n'est pas ainsi qu'on formule une telle expression régulière.

Pourriez-vous m'aider à reformuler ?
Jean-Baptiste,
Développement logiciel, infographie, livres numériques et sites internet en Auvergne : www.bournisien.info
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Caractère non pris en charge par l'EDI

Message par graph100 »

gibet_b a écrit :Pour résoudre mon problème, je voulais tester si le code ascii "renvoyé" par :

Code : Tout sélectionner

MatchRegularExpression (*RegPonctuation, Str(Asc(caractere)))
était bien compris dans certaines plages, avec "l'expression régulière suivante" :
MatchRegularExpression () ne renvoie pas code ascii ?? mais je pense que j'ai mal compris ou bien la question est mal posée :!: :?:

Sinon, je ne crois pas que tu puisse définir des classes de caractères à partir de leur code ascii tel que tu l'as fait.
Fait une recherche sur le web.

la regex suivante : "123|145" va correspondre à la chaine de caractère '123' et aussi '145', et non au caractère chr(123)...

Mmh, avec "Str(Asc(caractere))" tu cherches a faire quoi ? n'oublie pas que dans certain cas utiliser Findstring() est plus efficace !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Caractère non pris en charge par l'EDI

Message par Ar-S »

Je veux bien un exemple concret de ce que tu veux faire pour cerner ta demande.
Là j'ai compris que tu cherches à tester si une chaine.s comporte des caractères de chr(xx) à chr(xx) c'est ça ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
gibet_b
Messages : 13
Inscription : lun. 03/déc./2012 18:15
Localisation : Au coeur des Combrailles (63)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par gibet_b »

Merci à tous les deux.

J'ai bien pensé que je n'avais peut-être rien compris aux expressions régulières :?

Alors, je vais essayer d'expliquer mon raisonnement.

Etant donné que lorsque je copie/colle certains caractères dans l'EDI, ils sont remplacés par des « ? », je ne peux pas faire un simple :

Code : Tout sélectionner

IF caractère = "—"
(ou une quelconque recherche de ce caractère dans une chaine composée de tous les signes de ponctuation qui m'intéresse)

Mon idée est donc de voir si le code ASCII du caractère saisi par l'utilisateur se situe dans telle ou telle plage, ou s'il est égal à telle valeur.

Grâce à :

Code : Tout sélectionner

Define *RegPonctuation = CreateRegularExpression(#PB_Any ,"[33-47]|[91-93]|[123-125]|130|[132-133]|[145-151]|171|180|187")
J'espérais vérifier que le code ASCII du caractère se situait entre 33 et 47, ou entre 91 et 93, ou entre 123 et 125, ou est égal à 130, ou est entre 132 et 133, ou est entre 145 et 151, ou est égal à 171, ou est égal à 180, ou est égal à 187.

Code : Tout sélectionner

Asc(caractere)
Renvoie le code ASCII d'un caractère, et j'ai ajouté :

Code : Tout sélectionner

Str(Asc(caractere))
Parce que MatchRegularExpression demande un string comme paramètre.

J'espère avoir été plus clair :oops:
Jean-Baptiste,
Développement logiciel, infographie, livres numériques et sites internet en Auvergne : www.bournisien.info
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par falsam »

Pour taper des caractères non pris en charge par l'éditeur de Pure basic, utilises la touche Alt + 0 + Asc.
exemple : Alt + 0 + 187 donneras »
gibet_b a écrit :Me revoilà pour chercher un peu d'éclaircissement sur les très obscurs expressions régulières 8)

Pour résoudre mon problème, je voulais tester si le code ascii "renvoyé" par :

Code : Tout sélectionner

MatchRegularExpression (*RegPonctuation, Str(Asc(caractere)))
était bien compris dans certaines plages, avec "l'expression régulière suivante" :

Code : Tout sélectionner

Define *RegPonctuation = CreateRegularExpression(#PB_Any ,"[33-47]|[91-93]|[123-125]|130|[132-133]|[145-151]|171|180|187")
Mais visiblement, ce n'est pas ainsi qu'on formule une telle expression régulière.
Effectivementça ne fonctionne pas. Ma solution n'est pas élégante mais en attendant mieux, elle répond à ta problématique.

Code : Tout sélectionner

Global Ponctuation.s

Ponctuation = "33|34|35|36|37|38|39|40|41|42|43|44|45|46|47"
Ponctuation + "|91|92|93|123|124|125|130|132|133"
Ponctuation + "|145|146|147|148|149|150|151|171|180|187"

Global *RegPonctuation = CreateRegularExpression(#PB_Any ,Ponctuation)

Procedure.l IsPonctuation(caractere.s)
  ProcedureReturn MatchRegularExpression (*RegPonctuation, Str(Asc(caractere)))
EndProcedure

;Quelques ponctuations
Debug IsPonctuation("!")
Debug IsPonctuation(",")
Debug IsPonctuation("»")
Debug Isponctuation("'")

;N'est pas une ponctuation
Debug IsPonctuation("a")
PS : Tu testes bien plus que des ponctuations:p
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par falsam »

Ayant oublié deux "|" j'ai corrigé le code précédent.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
gibet_b
Messages : 13
Inscription : lun. 03/déc./2012 18:15
Localisation : Au coeur des Combrailles (63)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par gibet_b »

falsam a écrit :Pour taper des caractères non pris en charge par l'éditeur de Pure basic, utilises la touche Alt + 0 + Asc.
exemple : Alt + 0 + 187 donneras »
Eh bien, grâce à cette astuce que je ne connaissais pas, la méthode que j'expose dans le premier post devrait pouvoir fonctionner.

Je vous tiens au courant !

Merci 1000 fois.
Jean-Baptiste,
Développement logiciel, infographie, livres numériques et sites internet en Auvergne : www.bournisien.info
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Caractère non pris en charge par l'EDI

Message par falsam »

Si cette astuces fonctionne chez toi, alors le code suivant fonctionne aussi :)

Code : Tout sélectionner

Global *RegPonctuation = CreateRegularExpression(#PB_Any , "[!-/]|[[]]|[{-}]|[‚]|[„-…]|[‘-—]|[«]|[´]|[»]")

Procedure.l IsPonctuation(caractere.s)
  ProcedureReturn MatchRegularExpression (*RegPonctuation, caractere)
EndProcedure

;Quelques ponctuations
Debug IsPonctuation("!")
Debug IsPonctuation(",")
Debug IsPonctuation("»")
Debug IsPonctuation("«")
Debug Isponctuation("'")

;N'est pas une ponctuation
Debug IsPonctuation("a")
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre