正则表达式去除文档类型声明

6
我正在寻找一个正则表达式,以从一组XML文档中删除以下doctype声明:
<!DOCTYPE refentry [ <!ENTITY % mathent SYSTEM "math.ent"> %mathent; ]>

<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook MathML Module V1.1b1//EN"
          "http://www.oasis-open.org/docbook/xml/mathml/1.1CR1/dbmathml.dtd">

这是stackoverflow等平台上非常常见的问题,但是所有的答案都无法处理两种情况。
我的天真想法是<!DOCTYPE((.|\n|\r)*?)(\"|])>可以正确匹配第二种情况,但却在第一种情况下失败(它在第一个">停止并留下了%mathen; ]>未匹配)。如果我尝试让正则表达式更贪婪一点,它将尝试消耗整个文档。
完整的测试用例:
2个回答

10

编辑:修正了评论匹配,感谢TheFiddler

嗯,你可以使用类似下面这样(并不是完全优美的)方法:

<!DOCTYPE[^>[]*(\[[^]]*\])?>

它匹配一个<!和直到>[的所有内容,后跟由[]包围的可选部分,最后跟一个>

用于测试的JSfiddle

更多细节;

<!DOCTYPE     -- matches the string <!DOCTYPE
[^>[]*        -- matches anything up to a > or [
(\[[^]]*\])?  -- matches an optional section surrounded by []
>             -- matches the string >

如果文档中的任何其他位置都有 ] 和 >,那么贪婪匹配将匹配太多。此外,即使它起作用,贪婪匹配也必须回溯。最好使用懒惰匹配。 - ErikE
这也将匹配文档中的<!-- -->注释(请检查我的问题中的xml测试文件)。然而,对<!DOCTYPE[^>[]*(\[[^]]*\])?>进行小改动似乎能够按预期工作,所以除非有更好的答案,否则我会接受这个 :) - The Fiddler
@TheFiddler 哦,是的,我漏了那个。已经更新了答案。 - Joachim Isaksson
@TheFiddler 说实话,你不必转义闭合的方括号 ]。 - ErikE

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接