【问题标题】:An algorithm for parsing a text解析文本的算法
【发布时间】:2016-07-19 04:15:05
【问题描述】:

我正在解析文本,现在遇到了一些挑战: 文本中的原始字符串是

"All time views: 4,12011 shoppers saved this home"

我想用一段代码来识别这句话的意思,即:

All time views: 4,120
11 shoppers saved this home

理想情况下,我想返回类似

的东西
{'views': 4,120, 'saved': 11}

这是流水数据,我在他们的网站上查了很多记录,发现“所有时间的浏览量”通常是 2 到 5 位,而“节省的购物者”可以是 1 位或 2 位。

PS:原始文本是通过从网页中删除所有html标签获得的,导致这种有线句子结构。原始 html 是:

<li>All time views: 4,120</li><li>11 shoppers saved this hom</li>

我的团队领导不想使用 html 标签来解析网页,因为网站会定期修改他们的 html。

有人有好主意吗?任何语言或伪代码或算法的简单描述都可以。谢谢。

【问题讨论】:

  • 4,120 和 11 之间应该有空格吗?还是原始文本中没有空格?
  • 去掉html标签后,没有空格了。最初,该 html 是
  • views...4,120
  • 11 个购物者已保存
  • 我应该保留所有
  • 标签吗?
  • 你能修改html解析器吗?这样我建议在第一个
  • 标记之后添加一个“特殊字符”,例如换行符 (\n)。这样你就可以得到两条线并立即知道它是哪条线......
  • 我会修改解析器,通常用至少一个空格替换标签,以避免将来丢失信息。
  • 标签: algorithm parsing text


    【解决方案1】:

    是的,您应该解析原始 html,因为标签通常会帮助您。

    在您提供的情况下,只要文本在记录之间保持一致,您就可以关闭标签。

    由于您没有要求特定语言,因此我将笼统地进行此操作。

    1)隔离一条记录所需的html(如果是每页一个,那应该没问题,如果是多条,则使用string.split)

    2) 找到“views:”的索引(起始字符位置)并添加 6(包括空格,但您当然应该测试)。您将保留该字符串,直到到达“

    3) 找到“购物者节省”的索引。然后找到之前的所有内容,直到到达“>”。大多数语言都可以很容易地像这样向后工作。如果不能,则在步骤 2 中获得的上一个索引之后搜索第一个 &lt;li&gt;。您可能需要修剪末尾的空间。这应该会产生代表购物者数量的文本。

    如果您要进行大量解析,那么值得您花时间编写一个可以传入以下参数的函数:

    1) 全文搜索 2)从结尾开始的字符串(将长度添加到索引) 3) 结束的字符串(不要加上长度)

    这将返回起始字符串结尾和结束字符串开头之间的所有内容,这将涵盖简单的工作。如果您需要更大的灵活性,可以添加更多参数来提供帮助。

    【讨论】:

      【解决方案2】:

      谢天谢地,正如4,12011 所指出的那样,您的号码中有一个逗号。当你有逗号时,你知道一件事:后面的数字正好是 3。

      “所有时间浏览量:4,12011 名购物者保存了这个家”

      您应该使用lastIndexOf(',') 等方法查找逗号。这意味着您将获得逗号的最后一个索引,因此如果您有:1,123,23223,您将找出它在 3 和 2 旁边,然后您可以解析出剩余的数字。

      这样您就不必阅读 HTML 标签(这会更容易)。第一个字符串是 input.substring(0, input.lastIndexOf(',') + 3),另一个是 input.substring(input.lastIndexOf(',') + 3)。这应该有效。

      注意:当位数≤3时,此方法无效。如果没有 HTML 标签,就真的不可能弄清楚。不过,您始终可以尝试阅读 HTML,在 HTML 标记上使用 indexOf()

      【讨论】:

      • 不过,如果您的所有时间观看次数少于 1,000,则不会有逗号。
      • 是的,我在最后一句中提到了这一点。但不可能准确地猜出这些数字是多少。
      • 谢谢两位!我将使用 html 标签,但逗号的想法真的很鼓舞人心,我从来没有想过。在某些情况下它应该很有用。
      【解决方案3】:

      告诉您的团队负责人,您必须解析 HTML 才能获得正确的结果...

      此代码可能对您有所帮助:

      $url = 'http://www.example.org/your-uri/';
      
      //  loads the URL as an object
      libxml_use_internal_errors(true);   
      $dom = DomDocument::loadHTMLFile($url);
      libxml_use_internal_errors(false);
      
      //  DomXPath helps you find the correct <ul> where those <li> are,
      //  maybe by the <ul> ID or Class, so THIS xPath is only for explanation
      //  it's not intended to work...
      $xpath = new DOMXPath($dom);
      $ul = $xpath->query("//html/body/the/path/to/the/ul[@id='TheIDoftheUL']/li");
      
      //  Assuming that the <ul> has ONLY 2 <li> tags, as you stated...
      $text = ['views' => $ul->item(0)->textContent, 'saved' => $ul->item(1)->textContent];
      

      如果以后HTML发生变化,只需要重构xpath即可。

      P.D.我刚刚测试过它并且它有效。我可以从我博客的一个blogroll中拉出2个&lt;li&gt;,(当然,我在查询方法中写了正确的路径)。

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签