java.lang.StackOverflowError tout en utilisant une expression régulière pour Analyser les grandes chaînes
C'est ma Regex
((?:(?:'[^']*')|[^;])*)[;]
Il tokenizes une chaîne de caractères sur des points-virgules. Par exemple,
Hello world; I am having a problem; using regex;
Résultat est de trois chaînes de
Hello world
I am having a problem
using regex
Mais quand j'utilise une grande chaîne d'entrée, j'obtiens cette erreur
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
Comment est-il la cause et comment puis-je le résoudre?
Quelle est la taille de la chaîne que vous êtes l'analyse?
OriginalL'auteur Ali | 2011-09-22
Vous devez vous connecter pour publier un commentaire.
Malheureusement, Java builtin regex soutien a des problèmes avec les regexes contenant répétitif de chemins alternatifs (qui est,
(A|B)*
). C'est compilé dans un appel récursif, ce qui entraîne une StackOverflow d'erreur lorsqu'il est utilisé sur une très grande chaîne.Une solution possible consiste à réécrire votre regex pour ne pas utiliser un repititive de remplacement, mais si votre but est de marquer une chaîne de caractères sur des points-virgules, vous n'avez pas besoin d'un complexe regex à tous les vraiment, il suffit d'utiliser Chaîne de caractères.split() avec un simple
";"
comme argument.Je pense que je n'ai pas mis mon cas, clairement, désolé pour ça. La chaîne n'est pas segmenté juste sur point-virgule, mais il sera sous forme de jeton sur de nombreux modèles dans le même temps, à la segmentation sur le point-virgule a tout juste un cas simple.
eh bien, d'une manière générale: essayez d'éviter de solutions de rechange dans un générique. Vous pourriez aussi offrir d'autres regex bibliothèques comme jregex un aller, même si je ne suis pas sûr que cela résoudrait le problème...
Pour de plus amples référence bugs.sun.com/bugdatabase/view_bug.do?bug_id=6337993
OriginalL'auteur Jeen Broekstra
Si vous avez vraiment besoin d'utiliser une regex qui déborde de votre tapis, vous pouvez augmenter la taille de votre stack, en passant quelque chose comme-Xss40m à la JVM.
OriginalL'auteur Andrew
Il pourrait aider à ajouter un
+
après la[^;]
, de sorte que vous avez de moins en moins de répétitions.N'est-il pas aussi une certaine construire qui dit que “si l'expression régulière correspondant à ce point, ne pas trace”? Peut-être que c'est pratique, trop. (Mise à jour: il est appelé les quantificateurs possessifs).
Un de complètement différent consiste à écrire une méthode utilitaire appelé
splitQuoted(char quote, char separator, CharSequence s)
explicitement parcourt la chaîne et se souvient qu'il a vu un nombre impair de citations. Dans cette méthode vous pourrez également gérer le cas que le caractère guillemet peut-être besoin d'être sans échappement lorsqu'il apparaît dans une chaîne entre guillemets.OriginalL'auteur Roland Illig