Здравствуйте!
Поискал на форуме, да не нашел.
Необходимо извлечь информацию, находящуюся между любыми двумя тегами.
Пример:
буфер="мусор...<tag>полезная_инфа</tag>снова_мусор..."
тег="tag"Делаю функцию, которая принимает буфер и тэг, внутри сама обрамляет тэг символами <,> и / (для закрывающего). Все бы было тривиально, если бы после закрывающего тега не было мусора. Реализовал все, кроме, собственно, вытаскивания полезной инфы.
Делаюн а чистом Си, так что регулярные выражения не предлагать.
Интересует общий алгоритм сего извлечения.
Что-то типа
если символ буфера==символ закрывающего тега
смотрим и сравниваем следующий символ
иначе записываем данные в массив.Еще проблема в том, что если таким образом проверять, некоторые данные могут просто не попасть в полезный массив.
К примеру в такой строке "garbage<tag>inside</tatags</tag>garbage"Такая задача, имхо, в xml-парсерах лежит. Может кто знаком?
>[оверквотинг удален]
>Что-то типа
>если символ буфера==символ закрывающего тега
> смотрим и сравниваем следующий символ
>иначе записываем данные в массив.
>
>Еще проблема в том, что если таким образом проверять, некоторые данные могут
>просто не попасть в полезный массив.
>К примеру в такой строке "garbage<tag>inside</tatags</tag>garbage"
>
>Такая задача, имхо, в xml-парсерах лежит. Может кто знаком?я таки думать шо вы имеете заблуждаться
на перле это решается в одну строку ... регексами
да и под С можно заюзать теже PCRE
>я таки думать шо вы имеете заблуждатьсяПрепод не заблуждается. Он %) велел на си, значит на си
>>я таки думать шо вы имеете заблуждаться
>
>Препод не заблуждается. Он %) велел на си, значит на сиЗря вы так :)
Если есть чего по теме, прошу.
Суть в следующем - есть сервер на сокетах неблокируемых, на него приходят строки подобного рода, нужно их распарсить и пустить в обиход :) (строки приходят в таком псевдо-xml виде - типа <quote><mytag>тарампарампам</mytag></quote>)
Все сделал, кроме этого.
Не хочу подрубать лишние библиотеки, глядел в сторону expat, но думаю это ведь не должно быть сложно написать самому.
Система центос 5.3, вам версии компиля надо?:)
Просто я не лютый си-программер, хотя здесь чисто скорее алгоритмическая задачи, чем программистская.
>Просто я не лютый си-программер, хотя здесь чисто скорее алгоритмическая задачи, чем
>программистская.Нет тут алгоритмической задачи.
>>Просто я не лютый си-программер, хотя здесь чисто скорее алгоритмическая задачи, чем
>>программистская.
>
>Нет тут алгоритмической задачи.Как и помощи от вас ,)
Вообщем, накидал такой код
buffer - входной буфер с сокета
tag_start, tag_end - соответственно открывающийся и закрывающий тегиif((s1=strstr(buffer,tag_start))!=NULL && (s2=strstr(s1,tag_end))!=NULL)
{
pos=0;
for(i=0,j=0;i<strlen(s1);i++)
{
if(s1[i]==tag_end[j])
{
n=pos=i;
eq=1;
do
{
if(s1[n+1]==tag_end[j+1])
{
n++;
j++;
}
else
{
eq=0;
j=0;
break;
}
} while(tag_end[j]!='\0');
}
else
{
eq=0;
}
}
printf("%d\n",pos);
}
else
{
printf("%s\n","Pattern not found or incorrect buffer string");
}
Собственно, запоминаем позицию. затем в цикле считываем до нее и получаем переменную между тегов,
>[оверквотинг удален]
> n++;
> j++;
> }
> else
> {
> eq=0;
> j=0;
> break;
> }
> } while(tag_end[j]!='\0');У меня смутное ощущение, что все эти строки можно заменить на вызов strncmp() или strcmp()
Так практичней будет.#include <string>
#include <algorithm>/***************************************************************************/
std::string get_text(const std::string& str) {
const std::string open_tag("<tag>");
const std::string close_tag("</tag>");std::string::const_iterator open = std::search(str.begin(), str.end(), open_tag.begin(), open_tag.end());
std::string::const_iterator close= std::search(str.begin(), str.end(), close_tag.begin(), close_tag.end());
if ( open == str.end() || close == str.end() ) {
return std::string();
}
std::advance(open, open_tag.length());
return std::string(open, close);
}/***************************************************************************/
int main(int argc, const char** argv) {
const std::string str("gkjeihgei<tag>needle text</tag>kjbsbv");
std::string result = get_text(str);return 0;
}/***************************************************************************/
а в сторону lex-bison не смотрел?
там как-то вроде можно было извратиться, чтоб поток принимался
а если буфер разумной длины и гарантированно содержит открывающий и закрывающий тэги - тогда вообще без проблем
>
> а в сторону lex-bison не смотрел?
> там как-то вроде можно было извратиться, чтоб поток принимался
> а если буфер разумной длины и гарантированно содержит открывающий и закрывающий
>тэги - тогда вообще без проблем
>
>Не-не, все делал без сторонних библиотек. Вообщем-то, работает как надо, еще чуток дополнить - и только фпуть!