запарился с pcre. всё началось с того что мне надо обычную строку разбить по словам. шаблон задаю самый обычный "\\s*". Строка "ababa q.1 w.2": то есть должно найтись 3 совпадения...но хрена чего он находит.код C++ Код (Text): ... int parse_str (char *str) pcre *hpe; const char *error, *buf; int erroroffset, i = 0, j = 0; int ovector[300], wsp[300], count = 0; if (!(hpe = pcre_compile ("\\s*", PCRE_CASELESS|PCRE_MULTILINE, &error, &erroroffset, NULL))) return -1; pcre_extra *f_ext=pcre_study (hpe, 0, &error); count = pcre_exec (hpe, f_ext, str, strlen(str), 0, 0, ovector, 300); ... на выходе count=1 что не соотвествует истине ( решил было подключить pcrecpp но тут же посыпались ошибки из-за Code Generation -> Runtime Library: собирал и проект и pcre как /MDd и как /MTdкод C++ Код (Text): msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in pcrecpp.lib(pcrecpp.obj) msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in pcrecpp.lib(pcrecpp.obj) pcrecpp.lib(pcrecpp.obj) : error LNK2019: unresolved external symbol __invalid_parameter_noinfo referenced in function "public: int __thiscall std::_String_const_iterator<char,struct std::char_traits<char>,class std::allocator<char> >::operator-(class std::_String_const_iterator<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " (??G?$_String_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEHABV01@@Z) pcrecpp мне не принципиален, но не могу одолеть почему шаблон в сишном pcre не хочет работать... кто сталкивался с этими проблемами или есть какие то идеи по её решению - помогите. ps. всё что нашёл в поиске - игра с /MDd и перекомпиляцией проектов с одинаковыми опциями... не помогло.
тебе больше подойдёт /\w+/ig , а совсем подойдёт /[a-zA-Z\.0-9]+/ig или /\s+/ig смотря что ты хотел сказать в /\s*/ig А вообще man perlretut или man perlrequick + у pcre есть утиль pcretest =)
в perl то проблем нету) проблемы только в сях ( при имитации опций ig вапще больше ничего не находится...странный этот сишный pcre)
Код (Text): \usr\local\bin> pcretest PCRE version 7.4 2007-09-21 re> /\s*/ig data> ababa q.1 w.2 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: data> re> /\w+/ig data> ababa q.1 w.2 0: ababa 0: q 0: 1 0: w 0: 2 data> re> /[a-zA-Z\.0-9]+/ig data> ababa q.1 w.2 0: ababa 0: q.1 0: w.2 data> re> /\s+/ig data> ababa q.1 w.2 0: 0: data>^C исходники pcretest поставляются вместе с pcre, если нужны могу приатачить
шаблон \s* определяет 0 или больше [ \t\r\n]. В вашем случае лучше \s+ (только-что проверил и \s* и \s+ выдают одинаковые и правильные результаты)
\s = [\ \t\r\n\f] => \s* = \s от 0 до oo => грубо говоря получим позиции всех символов +1 включая \f pcre_exec возвращает не количество, а смещение в строке найденой подстроки согласно шаблону ( It returns offsets to captured substrings) поэтому возвращаетcя 1
нет. \s* и \s+ вернут разные результаты loginrl_103 не слушай нас посмотри реализацию в pcredemo и pcretest (по твоему коду я так понял ты хотишь получить позиции "пробелов", а не список "слов" - "q.1" и "w.2" ты IMHO тоже считаешь словами)
loginrl_103 епанутся (простите не удержался) судя по тому что вам надо, не легче строку разбить по словам таким способом:? Код (Text): void split(const string& s, char c, vector<string>& V) { string::size_type i=0; string::size_type j=s.find(c) while(j != string::npos){ v.push_back(s.substr(i,j-1)); i=++j; j=s.find(c, j); if(j==string::npos) v.push_back(s.substr(i, s.length())); } } вызов осуществляется split(str,' ', vec); str - sting vec- vector PS. толи я дурак толи лыжи не едут, но смотря на ваш код мне становится страшно, что вы с ним хотите я не представляю, обясните если не трудно. ЗЫЫ. код не проверял, лень компилятор запускать. вроде правильно, если не забыл где скобку или запятую
dag проверил еще раз. в строке "fgh jkt 2324 .we.r.4. uigh kj", по крайней мере, шаблоны \s* и \s+ дают одинаковые результаты. ring4 Да наверно и еще проще можно. Особенно если от C++ отказаться. Например Код (Text): int StrSpaceSplit(char* str,char** sarr){ //предположим, что массив sarr достаточно длинен char c, cold; char* ps; char** psa; if((!str) || (!sarr)) return 0; for(ps=str, cold=0, psa=sarr ; c=*ps; cold=c, ps++) if(c==' ' || c=='\t' || c=='\r' || c=='\n') *ps=c=0; else if(!cold) { *psa=ps; psa++; } return (int)(sarr-psa); } тоже не проверял. в конце может 'return (int)(sarr-psa)/sizeof(char*)' надо..
Код (Text): #include <stdlib.h> #include <pcre.h> int main() { const char *errptr; int erroffset; const char *ababa="ababa q.1 w.2"; int ovector[1025]; int i; int position=0; int length=strlen(ababa); pcre *compiled=pcre_compile("\\s*", 0, &errptr, &erroffset,NULL); if (compiled!=NULL) { while (position<length) { int recursives_count=pcre_exec(compiled,NULL,ababa,length,position,0,ovector,1024); if (recursives_count<1) break; for (i=0;i<recursives_count;i++) { char *substring_start=(char *)ababa+ovector[2*i]; int substring_length=ovector[2*i+1]-ovector[2*i]; printf("%2d[%i-%i]: [%.*s]\n", i,ovector[2*i],ovector[2*i+1],substring_length,substring_start); }; position = ovector[1] + 1; }; pcre_free(compiled); }; return 0; }; для \s* Код (Text): 0[0-0]: [] 0[1-1]: [] 0[2-2]: [] 0[3-3]: [] 0[4-4]: [] 0[5-6]: [ ] 0[7-7]: [] 0[8-8]: [] 0[9-10]: [ ] 0[11-11]: [] 0[12-12]: [] для \s+ Код (Text): 0[5-6]: [ ] 0[9-10]: [ ] для \w+ Код (Text): 0[0-5]: [ababa] 0[6-7]: [q] 0[8-9]: [1] 0[10-11]: [w] 0[12-13]: [2] для [a-zA-Z\.0-9]+ Код (Text): 0[0-5]: [ababa] 0[6-9]: [q.1] 0[10-13]: [w.2] В коде есть небольшая ошибка , но думаю из него понятно как что работает =) P.S. ещё раз советую обратиться к man perlretut + man pcre + примеры из самого pcre P.P.S. Извини за многа букаф -)
dag Только-что посмотрел. У меня в вызове pcre_exec третьим параметром с конца (как называется не помню) стоит PCRE_NOTEMPTY.