【发布时间】:2020-03-14 21:09:54
【问题描述】:
我正在尝试提出一种算法来识别字符串是元素文本内容的一部分还是元素属性的一部分。
例如:
<a class="tag tag-red-dark" href="/keywords?q=PARTOFATTRIBUTE"> Found TEXTCONTENT </a>
如果您对TEXTCONTENT 或PARTOFATTRIBUTE 执行正则表达式,您可以运行此算法来检查它们是文本的一部分还是属性的一部分:
MatchCollection matches = Regex.Matches(html, @"(?i)TEXTCONTENT");
for (int i = matches.Count-1; i >= 0 ; i--){
Match m = matches[i];
int currentIndex = m.Index;
bool isTextContent = false;
while (html[currentIndex] != '<'){
currentIndex--;
if (html[currentIndex] == '>'){ // text is placed between > and <
isTextContent = true;
break;
}
}
if (isTextContent){
// do something with text content
}else{
// do something with attribute
}
}
但是算法很脆弱。如果你的 html 看起来像这样:
<a class="tag tag-red-dark" title="a>b" href="/keywords?q=PARTOFATTRIBUTE"> Found TEXTCONTENT </a>
PARTOFATTRIBUTE 将被识别为文本,但不是。
此外,您还可以在其中包含
<a class="tag tag-red-dark" title="a>b" href="/keywords?q=PARTOFATTRIBUTE"> < Found TEXTCONTENT </a>
在没有转义的文本中放置 放在属性中是有效的。是否可以仅根据其放置的环境来确定所选字符串是否是文本内容属性的一部分?
【问题讨论】:
-
一个想法:您可以引入一个名为 IsValidElement() 的方法,然后为每个开始和结束标记检查元素是否有效。如果它无效,则查找下一个结束标签。我还建议你先想出一个伪代码而不是代码本身。
-
您可以使用
HtmlAgilityPack或其他解析 Html 的第三方库,然后使用自定义验证逻辑检查所有元素 -
HTMLAgilityPack 与手动浏览 html 相比非常慢。在我的测试中,构建树最多需要 50 毫秒,而 Regex 需要不到 1 毫秒。此外,它不提供简单替换文本内容的功能。它所能做的就是用新创建的节点替换节点。
标签: c# html html-parsing