.Pattern = "(0?[1-9]|[12]\d|3[01])[ /](" & MOIS & ")[ /](\d{2,4})|((0[1-9]|[12]\d|3[01])/(0[13578]|1[02])|(0[1-9]|[12]\d|30)/(0[469]|11))/((16|17|18|19|20|21)\d\d)|(0[1-9]|[1]\d|[2][0-8])/02/((16|17|18|19|20|21)\d\d)|29/02/((17|18|19|21[0])[48]|(17|18|19|20|21)([13579][26]|[2468][048])|(160|200)[048])"
Non , j'ai pris ces formats juste pour tester.tu travailles sur un type de format décliné en "dddd d mmm yyyy" et "d mmmm yyyy".
Selon moi, le but du jeu est d'extraire une date quelle que soit la chaîne de caractères sous laquelle elle est écrite et d'en vérifier sa validité (ex : le 31 avril 2011 ou le 29 02 2011 ne sont pas valides, contrairement au 25 janvier 2011 ou le 29 février 2012).Le but du jeu c'est de pouvoir extraire un date au sein d'une string quelconque non et de de transformer cette sous-chaine valide, non ?
Alors comme cela me délasses, j'y vais à tâtons et m'amuse avec RegExp.
C'est avant tout un divertissement, je ne poursuis donc aucun but précis.
Const MOIS As String = _
"(janv(ier)?|févr(ier)?|mar(s)?|avr(il)?|mai?|juin?|juil(let)?|août?|sept(embre)?|oct(obre)?|nov(embre)?|déc(embre)?)"
| | L’opérateur de choix (aussi appelé opérateur d’alternation ou d’union d’ensembles) fait correspondre l’expression avant ou après l’opérateur. | abc|def correspond à "abc" ou "de |
? | Ce quantificateur, qui n’est reconnu comme tel qu’en dehors d’une classe de caractères (dans une classe il désigne littéralement le caractère correspondant), fait correspondre zéro ou une seule fois l’élément qui le précède. Contrairement à l’opérateur standard, l’élément qui précède peut être aussi un groupe. | ba? correspond à "b" ou "ba". |
Pattern | Chaine | Résultat |
abc|def | abc | abc |
abc|def | abcdef | abc,def |
abc|def | def | def |
ab(c|d)ef | abdef | abdef |
ab(c|d)ef | abcef | abcef |
(abc)|(def) | abcdef | abc,def |
(abc)|(def) | abdef | def |
Tu as raison mais ce n'est pas un risque à proprement parler, juste le fait de connaître la syntaxe, et c'est vrai que ce n'est pas toujours évidentTon dernier propos Jean-Marie, etaye les risques que j'évoquais avec l'opérateur | ...
"fran(ce|co|c)" correspond exclusivement à l'un des trois mots suivants : "franc", "france", "franco"
En revanche "fran[ceo]{1,2}" correspond à "franc, frane", "frano", "france", "franeo", "franco", etc...
Sub test()
Dim Matches, oRegexp, s
Set oRegexp = CreateObject("VBScript.RegExp")
s = "abcdef"
MsgBox "chaîne à traiter : " & s
With oRegexp
.Global = -1: .IgnoreCase = -1
.Pattern = "ab[cd]{1,2}ef"
Set Matches = .Execute(s)
If Matches.Count > 0 Then MsgBox "chaine correspondant au motif ab[cd]{1,2}ef : " & vbCrLf & Matches.item(0) Else _
MsgBox "chaine correspondant au motif ab[cd]{1,2}ef : " & vbCrLf & "aucun item trouvé"
.Pattern = "ab(c|d)ef"
Set Matches = .Execute(s)
If Matches.Count > 0 Then MsgBox "chaine correspondant au motif ab(c|d)ef : & vbcrlf & " & Matches.item(0) Else _
MsgBox "chaine correspondant au motif ab(c|d)ef : " & vbCrLf & "aucun item trouvé"
s = "abcef"
MsgBox "chaîne à traiter : " & s
.Pattern = "ab[cd]{1,2}ef"
Set Matches = .Execute(s)
If Matches.Count > 0 Then MsgBox "chaine correspondant au motif ab[cd]{1,2}ef : " & vbCrLf & Matches.item(0) Else _
MsgBox "chaine correspondant au motif ab[cd]{1,2}ef : " & vbCrLf & "aucun item trouvé"
.Pattern = "ab(c|d)ef"
Set Matches = .Execute(s)
If Matches.Count > 0 Then MsgBox "chaine correspondant au motif ab(c|d)ef : " & vbCrLf & Matches.item(0) Else _
MsgBox "chaine correspondant au motif ab(c|d)ef : " & vbCrLf & "aucun item trouvé"
End With
End Sub
Function testDate2(Cellule As Range, Rang As Integer) As String
'Application.Volatile
Dim oRexp, Match, Matches, MesMois, i As Integer, MaChaine As String, MonPattern As String, k As Byte
If Cellule = "" Then Exit Function
Set oRexp = CreateObject("vbscript.regexp")
MesMois = Array("janv(\s|\.\-|\.|\-|ier)", "(févr|fevr)(\s|\.\-|\.|\-|ier)", "mars(\s|\.\-|\.|\-)", "avr(\s|\.\-|\.|\-|il)", "mai(\s|\.\-|\.|\-)", "juin(\s|\.\-|\.|\-)", _
"juil(\s|\.\-|\.|\-|et)", "(août|aout)(\s|\.\-|\.|\-)", "sept(\s|\.\-|\.|\-|embre)", "oct(\s|\.\-|\.|\-|obre)", "nov(\s|\.\-|\.|\-|embre)", "(déc|dec)(\s|\.\-|\.|\-|embre)")
MaChaine = LCase(Cellule.Value)
With oRexp
.Global = True
.IgnoreCase = True
'traitement du mois
For i = LBound(MesMois) To UBound(MesMois)
.Pattern = MesMois(i)
Set Matches = .Execute(MaChaine)
If .test(MaChaine) = True Then
For k = 0 To Matches.Count - 1
MaChaine = Replace(Replace(Replace(MaChaine, Matches.item(k), "/" & Format(i + 1, "00") & "/"), " /", "/"), "/ ", "/")
Next k
End If
Next i
'traitement du jour
.Pattern = "(?:\s|\b)(\d{1})([ /-]\d{1,2}[ /-])(\d{2,4})(?:\s|\b)"
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " 0$1$2$3 ")
'traitement de l'année
.Pattern = "(?:\s|\b)(\d{1,2})([ /-]\d{1,2}[ /-])((?:0|1|2){1}[0-9])(?:\s|\b)" 'années 2000 à 2 chiffres
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " $1$220$3 ")
.Pattern = "(?:\s|\b)(\d{1,2})([ /-]\d{1,2}[ /-])((?:3|4|5|6|7|8|9){1}[0-9])(?:\s|\b)" 'années 1900 à 2 chiffres
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " $1$219$3 ")
.Pattern = "((0[1-9]|[12]\d|3[01])[ /-](0?[13578]|1[02])|(0[1-9]|[12]\d|30)[ /-](0?[469]|11))[ /-]((16|17|18|19|20|21)\d\d)|(0[1-9]|[1]\d|[2][0-8])[ /-]0?2[ /-]((16|17|18|19|20|21)\d\d)|29[ /-]0?2[ /-]((190|210)[48]|(17|18|19|20|21)([13579][26]|[2468][048])|(160|200)[048])"
If .test(MaChaine) = True Then
Set Matches = .Execute(MaChaine)
If Rang - 1 < Matches.Count Then testDate2 = Format(Matches(Rang - 1), "dd/mm/yyyy")
Else
If Rang = 1 Then testDate2 = "Aucune date valide"
End If
End With
End Function
je suis né le lundi 13 juillet 1964 à 15 heures
Aucune date valide
13/07/64
lundi 13 juillet 1964
je suis né le lundi 13 juillet 1964 à 15 heures et je me suis marié le 11 septembre 1992 à Saint-pierre
qu'il faut remplacer par"juil(\s|\.\-|\.|\-|et)"
"juil(\s|\.\-|\.|\-|let)"
Function testDate2(Cellule As Range, Rang As Integer) As String
'Application.Volatile
Dim oRexp, Match, Matches, MesMois, i As Integer, MaChaine As String, MonPattern As String, k As Byte
If Cellule = "" Then Exit Function
Set oRexp = CreateObject("vbscript.regexp")
MesMois = Array("janv(\s|\.\-|\.|\-|ier)", "(févr|fevr)(\s|\.\-|\.|\-|ier)", "mars(\s|\.\-|\.|\-)", "avr(\s|\.\-|\.|\-|il)", "mai(\s|\.\-|\.|\-)", "juin(\s|\.\-|\.|\-)", _
"juil(\s|\.\-|\.|\-|let)", "(août|aout)(\s|\.\-|\.|\-)", "sept(\s|\.\-|\.|\-|embre)", "oct(\s|\.\-|\.|\-|obre)", "nov(\s|\.\-|\.|\-|embre)", "(déc|dec)(\s|\.\-|\.|\-|embre)")
MaChaine = LCase(Cellule.Value)
With oRexp
.Global = True
.IgnoreCase = True
'traitement du mois
For i = LBound(MesMois) To UBound(MesMois)
.Pattern = MesMois(i)
Set Matches = .Execute(MaChaine)
If .test(MaChaine) = True Then
For k = 0 To Matches.Count - 1
MaChaine = Replace(Replace(Replace(MaChaine, Matches.item(k), "/" & Format(i + 1, "00") & "/"), " /", "/"), "/ ", "/")
Next k
End If
Next i
'traitement du jour
.Pattern = "(?:\s|\b)(\d{1})([ /-]\d{1,2}[ /-])(\d{2,4})(?:\s|\b)"
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " 0$1$2$3 ")
'traitement de l'année
.Pattern = "(?:\s|\b)(\d{1,2})([ /-]\d{1,2}[ /-])((?:0|1|2){1}[0-9])(?:\s|\b)" 'années 2000 à 2 chiffres
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " $1$220$3 ")
.Pattern = "(?:\s|\b)(\d{1,2})([ /-]\d{1,2}[ /-])((?:3|4|5|6|7|8|9){1}[0-9])(?:\s|\b)" 'années 1900 à 2 chiffres
Set Matches = .Execute(MaChaine)
MaChaine = .Replace(MaChaine, " $1$219$3 ")
.Pattern = "((0[1-9]|[12]\d|3[01])[ /-](0?[13578]|1[02])|(0[1-9]|[12]\d|30)[ /-](0?[469]|11))[ /-]((16|17|18|19|20|21)\d\d)|(0[1-9]|[1]\d|[2][0-8])[ /-]0?2[ /-]((16|17|18|19|20|21)\d\d)|29[ /-]0?2[ /-]((190|210)[48]|(17|18|19|20|21)([13579][26]|[2468][048])|(160|200)[048])"
If .test(MaChaine) = True Then
Set Matches = .Execute(MaChaine)
If Rang - 1 < Matches.Count Then testDate2 = Format(Matches(Rang - 1), "dd/mm/yyyy")
Else
If Rang = 1 Then testDate2 = "Aucune date valide"
End If
End With
End Function
Re Dull,
Bravo pour ce test.
C'est simplement parce que le 2ème l (lettre L) de juillet avait été oublié dans le motif qu'il faut remplacer par
...
"juil(\s|\.\-|\.|\-|et)"
"juil(\s|\.\-|\.|\-|let)"
Mais c'est le but des testsje poursuis mes tests et tacherais de te coller une nouvelle fois
, mais également les différents formats de chaîne de caractères avec le jour et l'année en chiffres (pour le jour 1 ou 2 chiffres et pour l'année 2 ou 4 chiffres)....01/01/1654............2 janv 1889.............3 3 65.......4 6-09...