Ответ 1
В Perl вы можете использовать re::regexp_pattern
.
my $re = qr/foo/i;
my ($pat, $mods) = re::regexp_pattern($re);
say $pat; # foo
say $mods; # i
Как вы можете видеть из источника regexp_pattern
, в API нет никакой функции для получения этой информации, поэтому я рекомендую вам тоже вызовите эту функцию из XS.
perlcall охватывает вызовы Perl-функций из C. Я придумал следующий непроверенный код:
/* Calls re::regexp_pattern to extract the pattern
* and flags from a compiled regex.
*
* When re isn't a compiled regex, returns false,
* and *pat_ptr and *flags_ptr are set to NULL.
*
* The caller must free() *pat_ptr and *flags_ptr.
*/
static int regexp_pattern(char ** pat_ptr, char ** flags_ptr, SV * re) {
dSP;
int count;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(re);
PUTBACK;
count = call_pv("re::regexp_pattern", G_ARRAY);
SPAGAIN;
if (count == 2) {
/* Pop last one first. */
SV * flags_sv = POPs;
SV * pat_sv = POPs;
/* XXX Assumes no NUL in pattern */
char * pat = SvPVutf8_nolen(pat_sv);
char * flags = SvPVutf8_nolen(flags_sv);
*pat_ptr = strdup(pat);
*flags_ptr = strdup(flags);
} else {
*pat_ptr = NULL;
*flags_ptr = NULL;
}
PUTBACK;
FREETMPS;
LEAVE;
return *pat_ptr != NULL;
}
Использование:
SV * re = ...;
char * pat;
char * flags;
regexp_pattern(&pat, &flags, re);