Estoy trabajando en un JMD (Java MarkDown) (un puerto Java de MarkDownSharp) pero estoy teniendo un problema con una expresión regular en particular. Para el archivo de Markdown_Documentation_Syntax.text esta expresión regular muere:Java Regex muere en el desbordamiento de la pila: necesita una versión mejor
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);
que se traduce en:
(^<(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))
Este patrón está buscando etiquetas de bloque aceptados que se anclan en el comienzo de una línea, seguido de cualquier número de líneas y luego terminan con una etiqueta coincidente seguida de una nueva línea o un terminador de cadena. Esto genera:
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)
...
Esto puede ser tratado mediante el aumento del espacio de pila para Java (por defecto a 128k/400k para oss/ss IIRC), pero la expresión anterior es lento de todos modos.
Así que estoy buscando un gurú regex que pueda hacerlo mejor (o al menos explicar el problema de rendimiento con este patrón). La versión de C# es un poco lenta pero funciona bien. PHP parece no tener problemas con esto tampoco.
Editar: Esto es en JDK6u17 que se ejecuta en Windows 7 64 Ultimate.
¿qué versiones de JDK? – bmargulies
Este es un uso horrible de expresiones regulares. ¿Tienes que usar expresiones regulares o puedes cambiar esto como un analizador recursivo real (ya sea LR o descenso recursivo)? –
¿Has probado con '. * \ N' a'. *? \ N'? – YOU