我正在开发一个JMD(Java MarkDown)(MarkDownSharp的Java移植版),但我遇到了一个特定正则表达式的问题。对于文件Markdown_Documentation_Syntax.text,这个正则表达式会失败:
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);
翻译为:
(^<(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))
这个模式是寻找以行首为锚点的已接受的块标签,后跟任意数量的行,然后由匹配的标签终止,后跟换行符或字符串终止符。这将生成:
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)
...
可以通过增加Java的堆栈空间来解决这个问题(默认为128k / 400k,如果我没记错的话),但上述表达式仍然很慢。
因此,我正在寻找一个正则表达式大师,他可以做得更好(或者至少解释一下这个模式的性能问题)。 C#版本有点慢,但运行良好。 PHP似乎也没有这个问题。
编辑:这是在Windows 7 64 Ultimate上运行的JDK6u17。
.*\n
替换为.*?\n
吗? - YOU