Поиск всех экземпляров подстроки в строке - PullRequest
1 голос
/ 02 марта 2011

В мой последний вопрос Я спросил о разборе ссылок с HTML-страницы.Так как я еще не нашел решения, я подумал, что тем временем пробовал что-то еще: искать все <a href= и копировать все, что есть, пока не наберу </a>.

Теперь мой C немного заржавел, но я помню, что могу использовать strstr(), чтобы получить первый экземпляр этой строки, но как мне получить остальные?оценили.

PS: Нет. Это не домашняя работа в школе или что-то в этом роде.Просто чтобы ты знал.

Ответы [ 5 ]

4 голосов
/ 02 марта 2011

Вы можете использовать цикл:

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
  }
}
3 голосов
/ 02 марта 2011

Почему бы не использовать libxml , в который встроен очень хороший анализатор HTML?

1 голос
/ 02 марта 2011

Хорошо, первоначальный ответ и мои комментарии, похоже, требовали больше информации, чем было удобно в разделе комментариев, поэтому я решил создать новый ответ.

Прежде всего, то, что вы пытаетесь сделать IS задача программирования, для которой БУДЕТ требуется определенная способность программирования, в зависимости от ваших конкретных потребностей.

Во-вторых, были предоставлены некоторые ответы, в которых предлагается использовать циклы поиска символов и регулярные выражения. Оба из них ужасно подвержены ошибкам способы сделать вещи, как обсуждалось, например, здесь .

Обычный способ парсинга 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

это обычно выписывает HREF часть всех элементов A в документе. Достойный учебник о том, для чего вы можете использовать XPath, например, здесь .

Боюсь, что в C это было бы несколько более запутанным, но идея та же самая, и это задача программирования.

Если это какая-то быстрая и грязная работа, вы можете использовать предложенный поиск strstr () или regexp без внешних библиотек. Однако имейте в виду, что в зависимости от конкретной задачи вы, скорее всего, пропустите ряд исходящих ссылок или неправильно прочитаете их содержание.

0 голосов
/ 02 марта 2011

Вот что я бы сделал (не проверял, просто моя идея):

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.

0 голосов
/ 02 марта 2011

C-строки - это просто указатели на первый символ;чтобы получить следующее совпадение, просто вызовите его снова и передайте указатель в конец предыдущего совпадения, которое вы получили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...