LINUX.ORG.RU

[perl] [xs] Регулярные выражения

 


0

1

Есть проблема, не понятно как использовать регулярки в xs. В инете нарыл пример http://www.mail-archive.com/perl-xs@perl.org/msg02059.html

SV*
regex_once(SV *regex_ref, SV *text) {
    SV *regex_sv;
    regexp *rx;
    char *stringarg, *stringbeg, *stringend;
    MAGIC *mg = NULL;

    if (!SvROK(regex_ref)) croak("not a ref");
    regex_sv = SvRV(regex_ref);
    if (!SvMAGICAL(regex_sv)) croak("No magic");
    mg       = mg_find(regex_sv, PERL_MAGIC_qr);
    rx       = (REGEXP*)mg->mg_obj;

    stringbeg = SvPV_nolen(text);
    stringarg = stringbeg;
    stringend = SvEND(text);

    pregexec(rx, stringarg, stringend, stringbeg, 1, text, 1);

    return newSVpv(stringbeg, rx->endp[0]);
}
С учетом документации ( http://perldoc.perl.org/perlapi.html#REGEXP-Functions ), и подставляя его в свои реалии, получаем такой кусок кода
SV *mask;
mask = *hv_fetch( hv, "mask", 4, 0);

SV *path_info;
path_info = *hv_fetch( hv, "path_info", 9, 0);

if (SvRXOK(mask)) {
    printf("\tmask is regexp\n");
            
    REGEXP *rx;
    rx = SvRX(mask);
                    
    char *strarg, *strbeg, *strend;
                    
    strbeg = SvPV_nolen(path_info);
    strarg = strbeg;
    strend = SvEND(path_info);
                    
    pregexec( rx, strarg, strend, strbeg, 1, path_info, 1 );
                    
    printf("\t\treg[%s][%s][%s]\n",strarg,strbeg,strend);
}

  1. Не ясно что вообще должно быть на выходе
  2. Ловлю ошибку, если делать как в примере
    warning: assignment from incompatible pointer type
    error: 'REGEXP' has no member named 'endp'
    
  3. В документации функция pregexec числится как недокументированная ( http://perldoc.perl.org/perlapi.html#Undocumented-functions )

Нужно просто поймать true/false при исполнении регулярки на строку.


Решение

Решение конкретно заданной проблемы оказалось очевидным (ниже). А вот если вопрос изучать глубже, то всё таки остаются вопросы, но это уже следующий этап. Резюмируем.

Документация Internals and C language interface > perlreapi http://perldoc.perl.org/perlreapi.html

Пример реализации http://frepan.org/src/GBARR/Regexp-0.004/Regexp.xs?pretty=1

Рабочий код из XS модуля для теста

void
testreg(mask,str)
		SV *mask;
		SV *str;
	CODE:
		printf("BEGIN test regexp\n");
		if (SvRXOK(mask)) {
			REGEXP *rx;
			rx = SvRX(mask);
			
			char *strarg, *strbeg, *strend;
			
			strbeg = SvPV_nolen(str);
			strarg = strbeg;
			strend = SvEND(str);
			
			if (pregexec( rx, strarg, strend, strbeg, 1, str, 1 )) {
				printf("regexp TRUE\n");
				//int matches = rx->nparens;
				//printf("matches[%d]\n",matches);
			} else {
				printf("regexp FALSE\n");
			}
		} else {
			printf("arg[mask] is not regexp\n");
		}
		printf("END test regexp\n");
Работает при следующем вызове
testreg(qr{^/blog/},'/blog/index.htm');

Несложно понять что будет результатом

BEGIN test regexp
regexp TRUE
END test regexp

kavkaz
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.