我有数百个文件(古代ASP和HTML),其中包含过时且通常完全无效的HTML代码。
在Visual Studio和ReSharper之间,如果编辑器窗口滚动到出现无效HTML的位置,则会标记此无效HTML并且很容易看到。但是,这两种工具都没有提供任何方法来快速修复整个项目中的错误。
ReSharper关注的前几个错误是未关闭或关闭但未打开的标签。有时这是因为开始和结束标签重叠 - 例如:
<font face=verdana size=5><b>some text</font></b>
<span><p>start of a paragraph
with multiple lines of <i><b>text/hmtl
</i> with a nice mix of junk</b>
</span></p>
有时在旧版本的HTML中允许打开没有相应结束标记的标记(或者生成HTML的工具不关心标准,因为某些浏览器通常弄明白作者的意思)。所以我试图清理的混乱有很多未关闭的HTML标签,应该关闭。
<font face = tahoma size=2>some more text<b><sup>*</sup></b>
...
...
</body>
</html>
只是为了更好的衡量,代码包含许多没有匹配开始标记的结束HTML标记。
</b><p>some text that is actually within closed tags</p>
</td>
</tr>
</table>
因此,除了编写一个新的应用程序来解析,标记和修复所有这些错误之外 - 是否有人有一些.Net正则表达式可用于定位并优选使用Visual Studio 2012的搜索和替换功能修复此内容?
虽然单个表达式可以很好地处理上述情况之一的多个表达式仍然非常有用。
对于重叠的HTML标记,我使用的是这个表达式:
(?n)(?<t1s>(?><(?<t1>\w+)[^>]*>))(?<c1>((?!</\k<t1>>)(\n|.))*?)(?<t2s>(?><(?!\k<t1>)(?<t2>(?>\w+))[^>]*>))(?<c2>((?!(</(\k<t1>|\k<t2>)>))(\n|.))*?)(?<t1e></\k<t1>>)(?<c3>(?>(\n|.)*?))(?<t2e></\k<t2>>)
Explanation:
(?n) Ignore unnamed captures.
(?<t1s>(?><(?<t1>\w+)[^>]*>)) Get the first tag, capturing the full tag and attributes
for replacement and the name alone for further matching.
(?<c1>((?!</\k<t1>>)(\n|.))*?) Capture content between the first and second tag.
(?<t2s>(?><(?!\k<t1>)(?<t2>(?>\w+))[^>]*>)) Get the 2nd tag, capturing the full
tag and attributes for replacement, the name along for further matching, and ensuring
it does not match the 1st tag and that the first tag is still open.
(?<c2>((?!(</(\k<t1>|\k<t2>)>))(\n|.))*?) Capture content between the second tag
closing of the first tag.
(?<t1e></\k<t1>>) Capture the closing of the first tag, where the second tag is
still open.
(?<c3>(?>(\n|.)*?)) Capture content between the closing of the first tag and the closing
of the second tag.
(?<t2e></\k<t2>>) Capture the closing of the second tag.
用这个替换表达式:
${t1s}${c1}${t2s}${c2}${t2e}${c3}${t1e}
此搜索表达式的问题在于它非常缓慢。使用.
代替(\n|.)
进行三次内容捕获会更快,但会将结果限制为重叠标记和插入内容在一行中的结果。
如果第一个标记出现在第二个标记的内容中,表达式也将匹配有效,正确关闭和正确嵌套的HTML,如下所示:
<font color=green><b>hello world</b></font><span class="whatever"><font color=red>*</font></span>
因此,在“全部替换”操作中使用表达式是不安全的,尤其是在解决方案中的数百个文件中。
对于未关闭的代码,我已成功处理了自动结算代码:<img/>
,<meta/>
,<input/>
,<link/>
,<br/>
和{ {1}}。但是,我还没有尝试过所有其他标签的通用案例 - 可能包含内容的标签,或者应该使用单独的结束标签关闭。
另外,我不知道如何在没有匹配的开始标记的情况下匹配结束标记。 <hr/>
的简单解决方案将匹配所有结束标记,无论它们是否具有匹配的开始标记。
答案 0 :(得分:1)
根据他们的网站,Resharper有这个功能:
ReSharper不仅能够分析特定代码文件的错误,而且还可以扩展其分析技能,以涵盖整个解决方案。
...
您所要做的就是明确切换解决方案范围分析,然后在分析解决方案的代码后,在专用窗口中查看错误列表:
[
即使没有打开该窗口,您仍然可以使用解决方案中的转到下一个错误轻松浏览解决方案中的错误( Shift + Alt + PageDown < / kbd>)并转到解决方案中的上一个错误( Shift + Alt + F12 )命令。
第二个想法,可能有一个我们可以使用正则表达式的解决方案。
对于这个HTML:
<i><b>text/html
</i> with a nice mix of junk</b>
更好的转变(它更有效,对吗?):
<i><\i><b><i>text/hmtl
</i> with a nice mix of junk</b>
有很多方法可能会出错,(虽然它现在非常糟糕),但我认为你已经全部备份了。这个正则表达式(其中i
是您可能想要执行此操作的标记示例):
<(i(?: [^>]+)?)>([^<]*)<(\/?[^i](?: [^>]+)?)>
可能会帮助你。我不知道正则表达式替换是如何工作的,无论你使用什么样的风格,但如果用<$1>$2</$1><$3><$1>
替换$ 0(正则表达式匹配的所有内容),你将得到我正在谈论的转换。