Bonjour,

J'ai un énorme problème de performance avec une expression régulière dans de très rares cas. Quelqu'un pourrait-il m'aider à améliorer ces performances ?

L'exemple ci-dessus présente un texte qui est parsé assez rapidement (pas de match trouvé, c'est normal), mais quand j'ajoute des caractères par exemple au début de "général", le temps d'exécution augmente de façon exponentielle :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
  public static void main(String[] args) {
    Pattern pattern = Pattern.compile("\\{\\{(\\s*[lL]\\Qoupe\\E\\s*(?:\\|((?:(?:[^\\{\\}]*)|(?:\\{\\{\\!\\}\\}))*))?)\\}\\}");
    Matcher matcher = pattern.matcher("{{loupe|c=U [[général]] fut {{rom|II|2}}de .}} [[Lozère]]");
    long begin = System.currentTimeMillis();
    while (matcher.find()) {
      System.out.println("Found: " + matcher.start() + "," + matcher.end());
    }
    long end = System.currentTimeMillis();
    System.out.println("Done in " + (end - begin) + "ms");
  }
  • chaine initiale: 797ms
  • 1 caractère supplémentaire: 1797ms
  • 2 caractères supplémentaires: 3515ms
  • 3 caractères supplémentaires: 6984ms
  • 4 caractères supplémentaires: 13922ms
  • 5 caractères supplémentaires: 27813ms
  • 6 caractères supplémentaires: 55672ms

... en gros, 1 caractère de plus = 2 fois plus de temps

Explications du pattern
Code : Sélectionner tout - Visualiser dans une fenêtre à part
"\\{\\{(\\s*[lL]\\Qoupe\\E\\s*(?:\\|((?:(?:[^\\{\\}]*)|(?:\\{\\{\\!\\}\\}))*))?)\\}\\}"
Ce que j'essaye de faire, c'est trouver les chaînes de caractères qui respectent tous les critères suivants :
* commencent par {{
* puis un nombre quelconque de caractères blancs
* puis un texte donné, la première lettre pouvant être en majuscules ou minuscules (dans l'exemple, c'est loupe ou Loupe)
* puis un nombre quelconque de caractères blancs
* puis un nombre quelconque de paramètres séparés par des | (les paramètres ne devant pas contenir de { ou de } sauf si c'est {{!}}). Quand j'ai trouvé le texte, j'ai besoin d'avoir la valeur des paramètres.
* finissent par }}

Voilà, toute aide est la bienvenue

Nico