HTML 属性的正则表达式解析 - 一个特定字符串
RegEx Parsing for HTML attributes - one specific string
对于 Delphi Rio,我使用的是 HTML/DOM 解析器。我正在遍历各个节点,解析器正在 returning attributes/tags。通常这些都不是问题,但对于某些 attributes/tag,字符串 returned 包含多个属性。我需要将此字符串解析为某种类型的容器,例如字符串列表。解析器 returns 的属性字符串已经删除了“<”和“>”。
属性字符串的一些示例是:
data-partnumber="BB3312" class=""
class="cb10"
account_number = "11432" model = "pay_plan"
我想要的最终结果是一个 StringList,其中包含一个或多个名称=值对。
我没有真正使用过 RegEx,但我认为我想使用 RegEx。这是一种有效的方法吗?对于 RegEx 模式,我认为我想要的模式是
\w\s?=\s?\"[^"]+"
要识别一个字符串中的多个匹配项,我会使用 TRegex.Matches。我是不是忽略了一些会在以后引起问题的东西?
*** 附加信息 ***
有几个人建议使用像样的解析器。我目前正在使用此处找到的开源 HTML/DOM 解析器:https://github.com/sandbil/HTML-Parser
鉴于此,我发布了更多信息...这是我正在解析的 HTML 片段。看看我在末尾添加了 *** 的行。我的解析器 return 将其转换为
Node.AttributeText= 'data-partnumber="B92024" data-model="pay_as_you_go" class="" '
一个不同的 HTML DOM 解析器 return 会是 3 个不同的 elements/attributes 吗?如果是这样,有人可以推荐解析器吗?
<section class="cc02 cc02v0" data-trackas="cc02" data-ocomid="cc02">
<div class="cc02w1">
<div class="otable otable-scrolling">
<div class="otable-w1">
<table class="otable-w2">
<thead>
<tr>
<th>Product</th>
<th>Unit Price</th>
<th>Metric</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cb152title"><div>MySQL Database for HeatWave-Standard-E3</div></td>
<td><div data-partnumber="B92024" data-model="pay_as_you_go" class="">[=14=].3536<span></span></div></td> *****
<td><div>Node per hour</div></td>
</tr>
<tr data-partnumber="B92426">
<td class="cb152title">MySQL Database—Storage</td>
<td><span data-model="pay_as_you_go" class="">[=14=].04<span></span></span></td>
<td>Gigabyte storage capacity per month</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
(由于 OP 询问使用 RegEx 来解析属性=值对,这直接回答了问题,其他用户将来可能会寻找。)
基于正则表达式的答案
使用 RegEx 非常强大,从您提供的数据中,您可以使用以下方法提取属性名称和值对:
(\S+)\s*=\s*(\"?)([^"]*)(|\s|$)
这里使用了分组,解释如下:
第一个结果组是属性名(匹配非空白字符)
如果存在,第二个结果组是一个封闭的 "
,否则是一个空字符串
第三组结果为属性值
由于 RegEx 可以 运行 递归,您可以使用 MatchAgain 查看是否有另一个匹配项,因此递归读取所有属性。
procedure ParseAttributes(AInput: String; ATarget: TStringList);
var
LMatched: Boolean;
begin
pRegEx:=TPerlRegEx.Create;
try
pRegEx.RegEx:='(\S+)\s*=\s*(\"?)([^"]*)(|\s|$)';
pRegEx.Subject:=AInputData;
LMatched:=pRegEx.Match;
while LMatched do
begin
ATarget.Add(pRegEx.Groups[1].'='+'"'+pRegEx.Groups[3]+'"');
LMatched:=pRegEx.MatchAgain;
end;
finally
pRegEx.Free;
end;
end;
免责声明:我还没有尝试编译该代码,但希望它足以让你开始!
实用点:关于您用 DOM 解析器提出的实际问题 - 这是一项存在现有解决方案的任务 实用 解决问题的答案很可能是使用有效的 DOM 解析器!如果正则表达式是您出于某种原因需要的东西,那么这个应该可以胜任。
您正在使用的解析器的文档说 TDomTreeNode
有一个 AttributesText
属性,它是一个“ 具有所有属性的字符串 ” ,您已经展示了其中的示例。但它 也 有一个 Attributes
属性 即“parsed attributes " 作为 TDictionary<string, string>
提供。您是否尝试过查看 属性 的值?您根本不需要使用 RegEx,只需枚举 TDictionary
的条目即可,例如:
var
Attr: TPair<string, string>;
for Attr in Node.Attributes do begin
// use Attr.Key and Attr.Value as needed...
end;
对于 Delphi Rio,我使用的是 HTML/DOM 解析器。我正在遍历各个节点,解析器正在 returning attributes/tags。通常这些都不是问题,但对于某些 attributes/tag,字符串 returned 包含多个属性。我需要将此字符串解析为某种类型的容器,例如字符串列表。解析器 returns 的属性字符串已经删除了“<”和“>”。
属性字符串的一些示例是:
data-partnumber="BB3312" class=""
class="cb10"
account_number = "11432" model = "pay_plan"
我想要的最终结果是一个 StringList,其中包含一个或多个名称=值对。 我没有真正使用过 RegEx,但我认为我想使用 RegEx。这是一种有效的方法吗?对于 RegEx 模式,我认为我想要的模式是
\w\s?=\s?\"[^"]+"
要识别一个字符串中的多个匹配项,我会使用 TRegex.Matches。我是不是忽略了一些会在以后引起问题的东西?
*** 附加信息 *** 有几个人建议使用像样的解析器。我目前正在使用此处找到的开源 HTML/DOM 解析器:https://github.com/sandbil/HTML-Parser 鉴于此,我发布了更多信息...这是我正在解析的 HTML 片段。看看我在末尾添加了 *** 的行。我的解析器 return 将其转换为
Node.AttributeText= 'data-partnumber="B92024" data-model="pay_as_you_go" class="" '
一个不同的 HTML DOM 解析器 return 会是 3 个不同的 elements/attributes 吗?如果是这样,有人可以推荐解析器吗?
<section class="cc02 cc02v0" data-trackas="cc02" data-ocomid="cc02">
<div class="cc02w1">
<div class="otable otable-scrolling">
<div class="otable-w1">
<table class="otable-w2">
<thead>
<tr>
<th>Product</th>
<th>Unit Price</th>
<th>Metric</th>
</tr>
</thead>
<tbody>
<tr>
<td class="cb152title"><div>MySQL Database for HeatWave-Standard-E3</div></td>
<td><div data-partnumber="B92024" data-model="pay_as_you_go" class="">[=14=].3536<span></span></div></td> *****
<td><div>Node per hour</div></td>
</tr>
<tr data-partnumber="B92426">
<td class="cb152title">MySQL Database—Storage</td>
<td><span data-model="pay_as_you_go" class="">[=14=].04<span></span></span></td>
<td>Gigabyte storage capacity per month</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
(由于 OP 询问使用 RegEx 来解析属性=值对,这直接回答了问题,其他用户将来可能会寻找。)
基于正则表达式的答案
使用 RegEx 非常强大,从您提供的数据中,您可以使用以下方法提取属性名称和值对:
(\S+)\s*=\s*(\"?)([^"]*)(|\s|$)
这里使用了分组,解释如下:
第一个结果组是属性名(匹配非空白字符)
如果存在,第二个结果组是一个封闭的 "
,否则是一个空字符串
第三组结果为属性值
由于 RegEx 可以 运行 递归,您可以使用 MatchAgain 查看是否有另一个匹配项,因此递归读取所有属性。
procedure ParseAttributes(AInput: String; ATarget: TStringList);
var
LMatched: Boolean;
begin
pRegEx:=TPerlRegEx.Create;
try
pRegEx.RegEx:='(\S+)\s*=\s*(\"?)([^"]*)(|\s|$)';
pRegEx.Subject:=AInputData;
LMatched:=pRegEx.Match;
while LMatched do
begin
ATarget.Add(pRegEx.Groups[1].'='+'"'+pRegEx.Groups[3]+'"');
LMatched:=pRegEx.MatchAgain;
end;
finally
pRegEx.Free;
end;
end;
免责声明:我还没有尝试编译该代码,但希望它足以让你开始!
实用点:关于您用 DOM 解析器提出的实际问题 - 这是一项存在现有解决方案的任务 实用 解决问题的答案很可能是使用有效的 DOM 解析器!如果正则表达式是您出于某种原因需要的东西,那么这个应该可以胜任。
您正在使用的解析器的文档说 TDomTreeNode
有一个 AttributesText
属性,它是一个“ 具有所有属性的字符串 ” ,您已经展示了其中的示例。但它 也 有一个 Attributes
属性 即“parsed attributes " 作为 TDictionary<string, string>
提供。您是否尝试过查看 属性 的值?您根本不需要使用 RegEx,只需枚举 TDictionary
的条目即可,例如:
var
Attr: TPair<string, string>;
for Attr in Node.Attributes do begin
// use Attr.Key and Attr.Value as needed...
end;