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;