Je travaille sur un JMD (Java MarkDown) (un port Java de MarkDownSharp) mais j'ai un problème avec une regex en particulier. Pour le fichier Markdown_Documentation_Syntax.text cette expression régulière meurt:Java regex meurt sur débordement de pile: besoin d'une meilleure version
private static final String BLOCK_TAGS_1 = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del";
private static final String BLOCKS_NESTED_PATTERN = String.format("" +
"(" + // save in $1
"^" + // start of line (with MULTILINE)
"<(%s)" + // start tag = $2
"\\b" + // word break
"(.*\\n)*?" + // any number of lines, minimally matching
"</\\2>" + // the matching end tag
"[ \\t]*" + // trailing spaces/tags
"(?=\\n+|\\Z)" + // followed by a newline or end of
")", BLOCK_TAGS_1);
qui se traduit par:
(^<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b(.*\n)*?</\2>[ \t]*(?=\n+|\Z))
Ce modèle est à la recherche des balises de bloc acceptées qui sont fixés au début d'une ligne, suivi par un certain nombre de lignes, puis sont terminées par une balise correspondante suivie d'un retour à la ligne ou d'une terminaison de chaîne. Cela génère:
java.lang.StackOverflowError
at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3366)
at java.util.regex.Pattern$Curly.match0(Pattern.java:3782)
at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4357)
...
Cela peut être traitée en augmentant l'espace de pile pour Java (defaults 128k/400k pour oss/ss IIRC), mais l'expression ci-dessus est lent de toute façon. Donc, je suis à la recherche d'un gourou regex qui peut faire mieux (ou au moins expliquer le problème de performance avec ce modèle). La version C# est un peu lente mais fonctionne bien. PHP semble n'avoir aucun problème avec ça non plus.
Édition: Il s'agit de JDK6u17 exécuté sous Windows 7 64 Édition Intégrale.
quelles versions de JDK? – bmargulies
Ceci est une utilisation terrible des expressions régulières. Avez-vous besoin d'utiliser des regex ou pouvez-vous le refondre comme un vrai analyseur récursif (LR ou descente récursive)? –
Avez-vous essayé avec '. * \ N' à'. *? \ N'? – YOU