【问题标题】:Matching a term that contains nested HTML匹配包含嵌套 HTML 的术语
【发布时间】:2013-02-22 04:39:55
【问题描述】:

我一直无法找到解决此问题的方法。
我正在解析一些电子书的内容,找到特定的术语和字符,标记每个术语的位置和长度。

正常情况是这样的(摘自《权力的游戏》):

“当他停下来往下看时,他的头晕晕乎乎的,他感到手指在滑落。布兰哭了出来,紧紧抓住生命。”

如果我们要搜索字符“Bran”,它的位置是 85,长度是 4。很简单。

当有这样的段落时,我的问题就出现了:

<span height="-0em"><font size="7">D</font></span>aenerys Targaryen wed Khal Drogo

我们需要匹配“Daenerys Targaryn”。剥离 HTML 并匹配字符串很容易,但在此示例中,结果需要包含 HTML。因此,这里的预期结果是 location = 0, length = 67。

另一种情况,由散布在各处的随机锚标签引起:

Did anyone outside the Vale even suspect where Catelyn <a></a>Stark had taken him?

同样,搜索“Catelyn Stark”需要包含 HTML,因此 location = 47,length = 20。

我已经能够通过添加这些特定案例暂时解决它(专门搜索“Catelyn Stark),但显然我应该有一个更强大的解决方案,我似乎无法得到我的转过头来。我的尝试一直在使用 RegEx,但收效甚微。
我发现了有关 HTML 匹配/剥离(以及是否使用 RegEx =))的各种问题,但这种情况似乎有些独特。
剥离标签不是一种选择,因为必须保留内容。
这是在一个独立的 C# 应用程序中。
如果您的搜索比我的更好,任何想法、正确方向的步骤或类似示例将不胜感激!

【问题讨论】:

  • 为什么不能使用IndexOf Mehtod 和SubString() 方法和Length 方法..???
  • 你对位置和长度信息做了什么?
  • 呃。正则表达式不适合 html 解析...当然,您没有在这里显式解析 html,但您也可以这样做。我能给出的最佳建议是增加你的表达,为任何“标签”包含一些贪婪的前瞻匹配,即从小于到大于。
  • 除非您使问题更通用并适用于更广泛的背景,否则恐怕它“过于本地化”。还请解释为什么即使您没有使用 Regex 也需要 Regex,并发现为什么使用 Regex 进行 HTML 解析的能力范围从“理论上不可能”到“仅限于众所周知格式的非通用 HTML”。
  • 对不起,如果不清楚,但我并不特别需要正则表达式来匹配它,这只是我对尝试什么的初步感觉。任何适当的解决方案都会起作用。位置和长度信息用于在另一台设备上突出显示摘录中的字符,这需要包含 HTML

标签: c#


【解决方案1】:

一种可能的方法是在搜索字符串的每个字母之间插入以下内容:

(?:<[^>]*>)*

因此,当搜索字符“Bran”时,您的正则表达式将变为以下内容:

(?:<[^>]*>)*B(?:<[^>]*>)*r(?:<[^>]*>)*a(?:<[^>]*>)*n

这将允许您的正则表达式匹配搜索字符串中任意位置的任意数量的 HTML 标记。请注意,这仅在您的搜索字符串总是像字符名称这样简单的东西而不是正则表达式时才有效(如果您的搜索字符串中有 a* 这样的重复,此方法将失败)。

【讨论】:

  • 我希望有一些更优雅的东西,但现在可能必须这样做!谢谢
  • 这最终工作得很好。 string pattern = "(?:&lt;[^&gt;]*&gt;)*"; pattern = string.Format("{0}{1}{0}", pattern, string.Join(pattern, s.AsEnumerable())); 再次感谢!
【解决方案2】:

我将创建一个将“Daenerys Targaryn”作为参数的函数,然后去掉第一个字母。然后,它只会搜索“aenerys Targaryn”,如果找到,它会搜索“>D

例子:

public static string searchFor(string str)
{
  // strip first letter of search string (in this case "D")
  // search for the rest of the string ("aenerys Targaryn")
  // if found, search for ">D<"
  // if found, search for HTML tags with "D" inside (using regex)
  // if found, search for HTML tags with the previous HTML tag in them (using regex)
  return result;
}

【讨论】:

  • 这可能适用于首字母的情况。我可能会尝试 F.J 的解决方案并非在所有情况下都有效。谢谢!
【解决方案3】:

使用 Javascript 或 Php,您可以获得元素的文本和文档的文本并在那里搜索,然后执行正则表达式以返回最接近的匹配项(包含 html):

另一种选择:


将首先使用诸如 Lucene 搜索引擎之类的东西来索引书籍(它恰好可以让您以不同的格式进行索引(html 格式就是其中之一)。

然后您可以使用 Lucene api 更轻松地搜索您的文档。 在 php 中,我们有 Zend_Search_Lucene 非常适合这种事情。


Lucene 搜索可以在以下位置找到: http://lucene.apache.org/core/

玩得开心!

【讨论】:

  • 此外,zend search lucene 允许您设置可搜索区域的键。
  • 索引格式可以按照你喜欢的方式组织,然后根据键进行搜索。查看 zend_search_lucene api 以了解它是如何工作的,因为它听起来像是您尝试做的最佳解决方案。
  • 不幸的是,我在一个独立的应用程序中使用 C#,所以我不能使用任何 javascript 或 php 库。不过谢谢!
  • Lucene 搜索可用于大多数语言查找 c#。我搜索并找到了lucenenet.apache.org(c# 的一个端口)。看看吧,lucene 搜索引擎是相当强大的,已经存在了很长时间,并且已经在很多项目中进行了测试。
  • 还刚刚在使用 c#stackoverflow.com/questions/9004849/lucene-net-search-results 的堆栈上找到了 lucene 示例。祝你好运。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多