【问题标题】:Finding all instances of a substring in a string查找字符串中子字符串的所有实例
【发布时间】:2011-03-02 15:19:10
【问题描述】:

my last question 中,我询问了如何从 HTML 页面中解析链接。由于我还没有找到解决方案,因此我想我同时尝试了其他方法:搜索每个<a href= 并复制那里的任何内容,直到我找到</a>

现在,我的 C 有点生锈了,但我记得我可以使用 strstr() 来获取该字符串的第一个实例,但我如何获取其余的?

感谢任何帮助。

PS:不。这不是学校的家庭作业或类似的事情。让你知道。

【问题讨论】:

  • 坏主意,坏主意,注定要失败。当您点击<a href = ""<a href=''<a id="" href="" 或几乎数百 种几乎相同的<a> 标签编写方式时会发生什么?使用 XML 解析器。
  • 谢谢。我知道这是一个坏主意,但我还没有找到一个 XML 解析器,它不是超级复杂,有一个很好的例子来说明如何做到这一点。如果您知道一个(加上示例代码),请按我的方式发送

标签: c string


【解决方案1】:

你可以使用循环:

char   *ptr = haystack;
size_t nlen = strlen (needle);

while (ptr != NULL) {
  ptr = strstr (ptr, needle);
  if (ptr != NULL) {
    // do whatever with ptr
    ptr += nlen;  // hat tip to @larsman
  }
}

【讨论】:

  • 如果至少找到一次needle,则无限循环。您必须在每次迭代中超越比赛。此外,您必须检查NULL 之后 strstr
  • 鉴于 OP 的模式,我会在循环之前使用 ptr += strlen(needle)(或者更好的是 size_t nlen = strlen(needle)
  • 谢谢。如何检查我是否到达了?
  • @Mr Aleph:</a> 是你的一根针。您必须搜索 <a href= 作为循环中的第一针。然后在该条件内,再次搜索第二根针。
  • strncpy() 或类似的东西来取出字符串?
【解决方案2】:

为什么不使用libxml,它内置了一个非常好的 HTML 解析器?

【讨论】:

【解决方案3】:

好的,原来的答案和我的 cmets 似乎需要比评论部分更多的信息,所以我决定创建一个新答案。

首先,您正在尝试做的事情一项编程任务,需要一些编程能力,具体取决于您的具体需求。

其次,提供了一些答案,建议您使用 char 查找和正则表达式循环。正如所讨论的,这两种方法都非常容易出错,例如here

现在解析 HTML/XML 内容的常规方法是使用为此设计的外部库。事实上,这些库现在已经是某种标准,并且在许多编程语言中它们已经内置。

对于您的特殊需求,我对 C 和 XPath 都生疏,但它应该大致像这样工作:

  • 启动 XML/HTML 解析器。
  • 将您的 HTML 文档作为字符串加载到其中
  • 告诉解析器查找标签的所有实例(使用 XPath)
  • 它将返回给您一个“节点集”
  • 循环处理节点集,根据需要对每个标签进行处理

我找到了一些其他的例子,也许这个更好:http://xmlsoft.org/example.html

如您所见,有一个 XML 文档(没关系,因为 HTML 只是 XML 的子集,您的 HTML 文档也应该可以工作)。

在 Python 或类似语言中,这将非常容易,在某些伪代码中,这看起来像这样:

p=new HTMLParser
p->load(my html document)
resultset=p->XPath_Search("//a") # this will find all A elements in the HTML document
for each result of resultset:
   write(result.href)
end for

这通常会写出文档中所有 A 元素的 HREF 部分。 关于可以使用 XPath 做什么的一个不错的教程是 here

我担心在 C 中这会有点复杂,但想法是一样的,它是一个编程任务。

如果这是一些快速而肮脏的工作,您可以使用建议的 strstr() 或 regexp 搜索,而无需外部库。但是,请记住,根据您的具体任务,您很可能会错过一些传出链接或误读其内容。

【讨论】:

    【解决方案4】:

    C 字符串只是指向第一个字符的指针;要获得下一场比赛,只需再次调用它并将指针传递到您获得的上一场比赛的结尾。

    【讨论】:

      【解决方案5】:

      这是我会做的(未经测试,只是我的想法):

      char* hRef_start  = "<a href=";
      char* hRef_end    = "</a>";
      

      假设你的文字在

      char text[1000];
      char * first = strstr(text , hRef_start);
      if(first)
      {
          char * last = strstr(first , hRef_end);
          if(last)
               last--;
          else
               //Error here.
      
          char * link = malloc((last - first + 2) * sizeof(char));
          copy_link(link , first , last);
      }
      
      void copy_link(char * link , const char * first , const char * last)
      {
      
           while(first < last)
           {
                 *link = *first;
                 ++first;
           }
           *link = 0;
      }
      

      您应该检查malloc() 是否成功,并确保您free(),还要确保copy_link() 上没有任何参数是null

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-03
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        • 2013-07-01
        • 1970-01-01
        • 2017-08-05
        • 1970-01-01
        相关资源
        最近更新 更多