Page 1 sur 1

[R] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 09:26
par Zaibai
Bonjour à tous,

Je suis nouveau ici et je viens vous demander votre aide.

Je souhaite "créer" un pattern en OU avec caractère unique.
Je m'explique :)

Le but étant de proposé des lettres: txmcrhevciyu
Avec ces lettres proposés(12 lettres dans mon exemple), je veux trouver les mots faisables de 5 lettres. {5,5}
Donc je vais checker un fichier texte, y récupérer un mot de 5 lettres (par exemple merci).

Code : Tout sélectionner

$asResult = StringRegExp("merci", '[tcuméajxrieh\-\ ]{5,5}', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 6. Résultat = ", $asResult[0])
EndIf
Avec le code si dessus, correspondance ==> OK (c'est good pour moi)

Mais avec ce code aussi il y a correspondance:

Code : Tout sélectionner

$asResult = StringRegExp("mmmci", '[tcuméajxrieh\-\ ]{5,5}', 1)
If @error == 0 Then
    MsgBox(0, "SRE Exemple 6. Résultat = ", $asResult[0])
EndIf
Alors que mon pattern ne contient que un "m" et le string trois "m".
D'après mes désirs, pour qu'il y aurait correspondance il aurait fallu trois "m" dans mon pattern.
Comment faire pour rendre "unique" les caractères de mon pattern ?

NB: Les lettres proposés sont plus nombreuses ou égal aux mots faisables(en terme de lettres/caractères). (j'espère me faire comprendre) :?


J'avais fais quelque recherche et je pense que les expressions régulière sont une des solutions viables.
Si vous connaissez d'autre moyens/fonction/commande qui serait plus apte(notamment plus rapide) lors de l’exécution, je suis preneur.

Merci d'avance pour votre aide,
Cordialement,

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 11:07
par jguinch
Un truc comma ça ?
► Afficher le texte
Niveau rapidité, ça n'aura rien à voir avec un regex... Mais là je ne vois pas du tout comment faire ça avec des expressions régulières :?:


Edit : finalement, j'ai réussi à trouver un truc à base de regexp. Après, je sais pas si ma solution est la plus simple/rapide, mais voilà une idée :
► Afficher le texte

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 12:02
par mikell
Plus simple

Code : Tout sélectionner

$res1 = _Checkword("merci", "tcuméajxrieh- ")
Msgbox(0,"", $res1)

$res2 = _Checkword("memci", "tcuméajxrieh- ")
Msgbox(0,"", $res2)

$res3 = _Checkword("melci", "tcuméajxrieh- ")
Msgbox(0,"", $res3)

Func _Checkword($sWord, $sValidChars)
   Local $sLen = StringLen($sWord)
   $sWord = StringReplace($sWord, "-", "\-")
   Local $a = StringRegExp($sValidChars, '[' & $sWord & ']', 3)
   Return (UBound($a) = $sLen) ? 1 : 0
EndFunc

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 12:11
par jguinch
Super Mikell, j'avais pas pensé à faire comme ça... Carrément plus simple !

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 12:19
par jchd
Heureusement que Mikell a "échappé" le tiret entre-temps, j'allais poster un contre-exemple.
Un poil plus direct :

Code : Tout sélectionner

Func _Checkword($sWord, $sValidChars)
   Local $sLen = StringLen($sWord)
;~    $sWord = StringReplace($sWord, "-", "\-")
   Local $a = StringRegExp($sValidChars, '[\Q' & $sWord & '\E]', 3)
   Return (UBound($a) = $sLen) ? 1 : 0
EndFunc
 

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 12:21
par jguinch
Par la même occasion, JC vient de me montrer l'existance de \Q ... \E :D

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 12:39
par mikell
jchd a écrit :Heureusement que Mikell a "échappé" le tiret entre-temps, j'allais poster un contre-exemple.
Oui hein ?
Correction d'une réflexion pré-post incomplète ... :roll:

J'avais oublié le \Q ... \E que j'utilise rarement... loin des yeux loin du coeur :mrgreen:
Du coup ça simplifie encore

Code : Tout sélectionner

Func _Checkword($sWord, $sValidChars)
   Local $a = StringRegExp($sValidChars, '[\Q' & $sWord & '\E]', 3)
   Return (UBound($a) = StringLen($sWord)) ? 1 : 0
EndFunc

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 15:31
par Zaibai

Code : Tout sélectionner

Func _Checkword($sWord, $sValidChars)
   Local $a = StringRegExp($sValidChars, '[\Q' & $sWord & '\E]', 3)
   Return (UBound($a) = StringLen($sWord)) ? 1 : 0
EndFunc
Ce code est merveilleux ! Merci les mec !

Par contre, pouvez-vous m'expliquer clairement le pattern ? '[\Q' & $sWord & '\E]'

Ce que je pense comprendre:
[...] signifie OU ça OU ça (tel lettre ou encore tel lettre etc)
\Q ... \E permet en gros "d'ignorer/annuler/enlever" les caractères spéciaux.

Ce que je ne comprend pas:
Pourquoi faire plusieurs groupe de ' ' ('[\Q' '\E]')
Pourquoi mettre des " & " ? (avec des espaces autour) Et pourquoi il y a des espaces ? Sont-il important ? (' & & ') (espace entre les ' et &)

En tout cas, le code n'est pas long et simple ! (faut juste comprendre le pattern...)

Ce code me permettra de trouver quels mots pourra être effectué via des lettres proposés. (d’où l'utilité d'ignorer les caractères spéciaux (tiret, espace, etc)
Un peu comme ici en gros: http://www.capeutservir.com/mots/pluslong.php

Merci encore et merci d'avance pour vos futurs réponse.

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : lun. 02 juin 2014 23:27
par mikell
Zaibai a écrit :Ce que je pense comprendre:
[...] signifie OU ça OU ça (tel lettre ou encore tel lettre etc)
\Q ... \E permet en gros "d'ignorer/annuler/enlever" les caractères spéciaux.
A peu près exact. Cette séquence permet d'enlever aux caractères spéciaux leur attribut "spécial" et de les traiter dans la séquence comme des caractères "normaux"
Zaibai a écrit :Pourquoi faire plusieurs groupe de ' ' ('[\Q' '\E]')
Pourquoi mettre des " & " ? (avec des espaces autour) Et pourquoi il y a des espaces ? Sont-il important ? (' & & ') (espace entre les ' et &)
'[\Q' & $sWord & '\E]' est équivalent à '[\Qmerci\E]' ou à '[\Q' & 'merci' & '\E]'
C'est comme quand tu veux concaténer 2 strings :
$string = $string1 & $string2
$string = "abc" & "def"
$string = "abc" & $string2
Les espaces ne sont utiles que pour une meilleure lisibilité du code

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : mar. 03 juin 2014 11:49
par Zaibai
En effet la syntaxe est logique, j'aurais du le comprendre tout seul autant pour moi.

Après avoir testé plus en profondeur le code, le résultat n'est pas exactement celui voulu.

Exemple avec un code (avec commentaire):

Code : Tout sélectionner

Autoit letter suite :

$res1 = _Checkword("merci", "tcuméajxmmeh- ") ; non ok
Msgbox(0,"", $res1)

$res2 = _Checkword("mrrci", "tcuméajxrieh- ")
Msgbox(0,"", $res2)

$res3 = _Checkword("melci", "tcuméajxrieh- ")
Msgbox(0,"", $res3)

$res4 = _Checkword("merci", "tcuméajxrieh- ")
Msgbox(0,"", $res4)

Func _Checkword($sWord, $sValidChars)
   Local $a = StringRegExp($sValidChars, '[\Q' & $sWord & '\E]', 3) ; si j'inverse $sValidChars et $sWord le $res2 seras non ok et le $res1 ok. Ce qui est logique
   Return (UBound($a) = StringLen($sWord)) ? 1 : 0
EndFunc
 
Le $res1 n'est pas conforme à mes attentes ( $res1 = _Checkword("merci", "tcuméajxmmeh- ") ). Je m'explique.
Avec $res1 il y a correspondance alors qu'il ne devrait pas. dans les lettres proposés je n'ai pas de "r" ni de "i" mais vu que j'ai 3 "m" il y a correspondance...

En gros, il ne faut pas qu'il trouve plusieurs correspondance avec la même lettre... Et c'est là le problème...
Peut-on faire ça avec les expressions régulières ?

Ce qui reprend mon premier post:
Comment faire pour rendre "unique" les caractères de mon pattern ?
En tout cas merci du temps que vous me consacrez !

Re: [..] StringRegExp - Un Pattern OU avec caractère unique

Posté : mar. 03 juin 2014 14:27
par jchd
Le problème réside dans l'emploi d'une classe : l'unicité est impossible à détecter.

Une autre approche, moins simplissime :

Code : Tout sélectionner

Local $aMots = ["merci", "mer-ci", "me-mci", "hématie", "remercie-moi", "mariée", "xyz"]
Local $sFiltre = "tcuméajxrieh -"
Local $aTmp = StringSplit(StringReplace($sFiltre, '-', ChrW(0xFFFC)), "", 2)
_ArraySort($aTmp)
$sFiltre = _ArrayToString($aTmp, "")

For $sMot In $aMots
    Local $aTmp = StringSplit(StringReplace($sMot, '-', ChrW(0xFFFC)), "", 2)
    _ArraySort($aTmp)
    Local $sSorted = _ArrayToString($aTmp, ".*")
    Local $OK = StringRegExp($sFiltre, $sSorted, 0)
    ConsoleWrite($sMot & ($OK ? " convient." : " ne convient pas.") & @LF)
Next
 

Re: [R] StringRegExp - Un Pattern OU avec caractère unique

Posté : mar. 03 juin 2014 15:02
par Zaibai
Apparemment le mieux est de "jouer" avec les variables donc on en revient à la première solution de jguinch.

Voici le code fonctionnel en fonction de mes besoins:

Code : Tout sélectionner

$res1 = _Checkword("mercm", "tcuméajxmmeh- ") ; 0
ConsoleWrite($res1)
$res2 = _Checkword("mrrci", "tcuméajxrieh- ") ; 0
ConsoleWrite($res2)
$res3 = _Checkword("mérc i", "tcuméajxrieh- ") ; 1
ConsoleWrite($res3)
$res4 = _Checkword("m-rci", "tcuméajxrieh- ") ; 1
ConsoleWrite($res4)
Sleep(5000)

Func _Checkword($sWord, $sValidChars)
    Local $sChar
    For $i = 1 To StringLen($sWord)
        $sChar = StringMid($sWord, $i, 1)
        If StringInStr($sValidChars, $schar) Then
            $sValidChars = StringReplace($sValidChars, $sChar, "", 1)
        Else
            Return 0
        EndIf
    Next
    Return 1
EndFunc
En effet cela doit vous paraître simple mais je débute et je n'avais pas pensé à StringInStr et StringReplace.
Je pense que le sujet est résolu.
Merci beaucoup pour votre aide et je n'hésiterais pas à revenir vers vous :D :evil: