我将首先对文本做一些简化的假设。在尝试将 HTML 与正则表达式匹配时,这总是必要的,但在这种情况下,主要是为了使正则表达式更易于阅读。可以更正正则表达式以反映更复杂的标准,而无需更改其基本结构。
- 元素和属性名称总是按字母顺序排列(即,它们与 VS 的
:w
, 或匹配[A-Za-z]+
)。
- 属性名称前面总是有空格和/或制表符 (
:b+
)。
- 属性值始终用引号引起来 (
:q
)。
=
属性名称和它的值之间没有空格。
另外,请注意我在~(style):w
. 它说“一个或多个字母 ( :w
),但如果它们构成单词,则不是style
”。您正在使用它,就好像它是一个否定的后视:" <__@BGCOLOR{.@}>
,除非它前面是style=
"。很多人都会犯这个错误。
我提出了一个四步流程:
首先,匹配任何带有特殊标记的元素并重新排列它,以便将标记列在所有属性之后:
- 搜索:
{\<:w(:b+:w=:q)*}{:b+\<__\@BGCOLOR[^<>]*\>}{(:b+:w=:q)+}
- 代替:
\1\3\2
其次,如果有一个style
属性,请确保它是列出的最后一个属性(但在特殊标记之前):
- 搜索:
{\<:w(:b+~(style):w=:q)*}{:b+style=:q}{(:b+~(style):w=:q)+}{:b+\<__\@BGCOLOR[^<>]*\>}
- 代替:
\1\3\2\4
第三,将特殊标记包装在一个style
属性中:
- 搜索:
{\<__\@BGCOLOR[^<>]*\>}\>
- 代替:
style="\1">
最后,如果有两个style
属性,合并它们:
- 搜索:
style="{[^"]+}":b+style="{\<[^<>]+\>}"
- 代替:
style="\1; \2"
从这段文字开始:
<div <__@BGCOLOR> id="inner-box" style="border:1px">
<div foo="bar" id="inner-box" <__@BGCOLOR TOGGLE="1"> style="border:1px">
<div id="inner-box" bar="foo" <__@BGCOLOR>>
<div id="inner-box" <__@BGCOLOR> style="border:1px">
<div id="inner-box" style="border:1px" <__@BGCOLOR TOGGLE="1">>
<div id="inner-box" <__@BGCOLOR> foo="bar">
...我最终得到了这个:
<div id="inner-box" style="border:1px; <__@BGCOLOR>">
<div foo="bar" id="inner-box" style="border:1px; <__@BGCOLOR TOGGLE="1">">
<div id="inner-box" bar="foo" style="<__@BGCOLOR>">
<div id="inner-box" style="border:1px; <__@BGCOLOR>">
<div id="inner-box" style="border:1px; <__@BGCOLOR TOGGLE="1">">
<div id="inner-box" foo="bar" style="<__@BGCOLOR>">
我得告诉你,Visual Studio 是这里的主要障碍。这是一个很棒的 IDE,但它的正则表达式风格很奇怪。如果您打算做很多此类事情,我强烈建议您切换到像EditPad Pro或PowerGrep这样的工具,它使用标准语法的全功能正则表达式风格。
编辑:我终于做了(相对)明智的事情,并以类似 Perl 的风格编写了正则表达式,主要是为了找出问题是否可以用正则表达式解决。确实如此,而且只需要两个步骤:
搜索:
(
<\w+\b
(?:
\s*
(?:
\w+="[^"]+"
|
<(?!__@BGCOLOR)[^<>]*>
)
)*
\s*
)
(<__@BGCOLOR[^<>]*>)
(
(?:
\s*
(?:
\w+="[^"]+"
|
<[^<>]+>
)
)*
)
代替:
$1style="$2"$3
搜索:
(
<\w+\b
(?:
\s*
(?:
(?!style)\w+="[^"]+"
|
<[^<>]+>
)
)*
\s*
)
style="([^"]+)"
(
(?:
\s*
(?:
(?!style)\w+="[^"]+"
|
<[^<>]+>
)
)*
)
\s*style="([^"]+)"
代替:
$1style="$2; $4"$3
下一步是将其转换为 Visual Studio 语法(如果可能的话),但我现在太累了,无法开始。;) 而且,正如我之前所说,如果你要经常做这种事情,你应该考虑编写一个专用的解析器,或者切换到使用标准语法的工具或语言(对于非常松散的定义“标准”)。无论您做什么,都不要使用 Visual Studio 的本机所谓的正则表达式,您将对每个人都有帮助。:D