我已经定义了一个解析单个 HTML 标记的正则表达式。不过,我并没有解析整个 DOM 树,只是解析了单个标签,因此正则表达式似乎是一个很好的匹配项。
假设我有一个像这样的标签:
<input type="text" disabled value="Something" />
我定义了我的正则表达式来解析标签:
<(?<closing>/)?(?<tname>[a-z][a-z0-9]*)(?:\s+(?<aname>[a-z0-9-_:]+)(?:=(?<quote>['""])(?<avalue>[^'""<>]*)\k<quote>)?)*(?<selfclosing>\s*\/)?>
因此,为了使其更具可读性,让我们将其分解
1 <
2 (?<closing>/)?
3 (?<tname>[a-z][a-z0-9]*)
4 (?:\s+
5 (?<aname>[a-z0-9-_:]+)
6 (?:=
7 (?<quote>['""])
8 (?<avalue>[^'""<>]*)
9 \k<quote>
10 )?
11 )*
12 (?<selfclosing>\s*\/)?
13 >
线条:
- 1 & 13 - 标记开始和结束
- 2 & 12 - 无论是结束标签还是自结束标签
- 3 - 捕获标签名称
- 4-11 - 捕获在标签上定义的任何属性(因此
*
在末尾)
- 5 - 属性名称
- 6-10 - 如果存在则不捕获组属性值(因此
?
在末尾)
- 6 - 匹配
=
符号
- 7 - 定义使用的引号(单引号或双引号)
- 8 - 捕获属性值
- 9 - 匹配用于打开属性值的相同结束引号
问题
当我尝试解析前面提到的具有三个属性的 input
标签时,我可以通过以下方式轻松访问所有属性名称:
match.Groups["aname"].Captures
但我也想匹配他们的值(value)观。所以这里存在一个问题,因为属性 2 没有值。
我如何匹配这些 match.Groups["aname"].Captures
与 match.Groups["avalue"].Captures
?我的正则表达式
考虑一下:
<
(?<closing>/)?
(?<tname>[a-z][a-z0-9]*)
(?:
\s+
(?<aname>[a-z0-9-_:]+)
(?:
=?
(?<quote>['"]?)
(?<avalue>[^'"<>]*)
\k<quote>
)
)*
(?<selfclosing>\s*\/)?
>
它将匹配一些无效的标记:
<input type="text" disabled"" value="Something" />
<input type="text" disabled= value="Something" />
但您可以通过添加前瞻来解决此问题:
<
(?<closing>/)?
(?<tname>[a-z][a-z0-9]*)
(?:
\s+
(?<aname>[a-z0-9-_:]+)
(?:
(?:
=
(?=\S)|
(?=\s)
)
(?<quote>['"]?)
(?<avalue>[^'"<>]*)
\k<quote>
)
)*
(?<selfclosing>\s*\/)?
>
aname
和 avalue
将对齐。
我是一名优秀的程序员,十分优秀!