
Envoyé par
joel.drigo
je ne mettrais pas de séparateur dans la flat string, parce que ça permet d'avoir le motif à n'importe quelle position, en ayant le même nombre de 0 de séparation
Si tu fais ça, tu n'as plus aucun moyen de savoir si des 1 sont sur la même ligne ou pas. Exemple:
0001110001000000000000000
qui vérifie pourtant la pattern, une fois disposé en tableau donne:
1 2 3 4 5
| 00011
10001
00000
00000
00000 |
On ne peut donc pas se passer du délimiteur de ligne. J'ai choisi ici un saut de ligne, mais n'importe quoi peut faire l'affaire (sauf un 0 ou un 1).
Pour alléger, je n'ai pas doublé les antislashes (il faudra donc le faire dans le code Java). Ces patterns sont destinées à la méthode matches, c'est pourquoi, les ancres \A et \z n'y figurent pas. Pour les utiliser avec une autre méthode, il faut penser à les rajouter au besoin.
Pour le I, c'est assez simple, on capture l'espace entre deux 1 en imposant une nouvelle ligne et en incluant le 1 suivant, puis on répète la backréférence:
[0\n]*1(0*\n0*1)\1+[0\n]*
Pour le L, c'est comme pour le I, il faut juste vérifier qu'il y a au moins un 1 supplémentaire qui suit:
[0\n]*1(0*\n0*1)\1+1+[0\n]*
Pour le T c'est plus difficile:
(?:0+\n)*(0*)(1+)1\2(0*)(\n\1(0+)1\5\3)\4*(?:\n0+)*
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| (?:0+\n)* # on écoule les éventuelles lignes de zéros
(0*) # on capture les zéros avant le chapeau du T (groupe 1)
(1+) # on capture les uns avant le 1 médian (groupe 2)
1 # 1 médian
\2 # on utilise une backréférence au groupe 2 (il doit y avoir le même nombre de 1 pour que ce soit symétrique)
(0*) # on capture les zéros aprés le chapeau du T (groupe 3) (jusqu'à la fin de la ligne)
( # on capture la première ligne de la tige (groupe 4)
\n
\1 # on a autant de zéros qu'avant le chapeau
(0+) # plus autant de zéros qu'il y a de 1 avant le 1 médian (groupe 5)
1 # le 1 de la tige
\5 # autant de zéros qu'il y a de 1 après le 1 médian (donc autant que dans le groupe 5)
\3 # autant de zéros qu'après le chapeau
)
\4* # on répète le groupe 4, jusqu'à arriver au bout de la tige
(?:\n0+)* # on complète avec les éventuelles lignes de zéros |
(?:0+\n)* et (?:\n0+)* permettent respectivement de s'assurer qu'on est bien au début ou à la fin d'une ligne.
On peut aussi passer certains quantificateurs en possessifs pour accélérer l'échec de la pattern:
(?:0+\n)*+(0*)(1+)1\2(0*)(\n\1(0+)1\5\3)\4*+(?:\n0+)*
Une représentation des groupes de capture et de leur backréférences pour bien visualiser
1 2 3 4 5 6 7
| 00000000000 XXXXXXXXXXX
00111110000 1122X223333
00001000000 1155X553333 => ligne capturée dans le groupe 4
00001000000 44444444444
00001000000 44444444444
00000000000 XXXXXXXXXXX
00000000000 XXXXXXXXXXX |
NB: on peut aussi l'écrire comme ça:(?:0+\n)*(0*)(1+)1\2(0*)(?:\n\1(0+)1\4\3)+(?:\n0+)*NB2: toutes ces patterns s'appuient sur le fait que les lignes ont la même longueur. Il est également possible de le faire si ce n'est pas le cas, mais les patterns sont plus complexes.
Partager