gpt4 book ai didi

c - 如何在 Perl API 中内省(introspection)正则表达式

转载 作者:太空狗 更新时间:2023-10-29 16:44:51 28 4
gpt4 key购买 nike

我正在处理一些需要序列化 ​​Perl 正则表达式的代码,包括任何正则表达式标志。仅支持一部分标志,因此我需要检测正则表达式对象中何时出现不受支持的标志,例如 /u

当前版本的代码是这样做的:

static void serialize_regex_flags(buffer *buf, SV *sv) {
char flags[] = {0,0,0,0,0,0};
unsigned int i = 0, f = 0;
STRLEN string_length;
char *string = SvPV(sv, string_length);

然后手动处理 string char-by-char 以查找标志。

这里的问题是正则表达式标志的字符串化改变了(我认为在 Perl 5.14 中)例如(?i-xsm:foo)(?^i:foo),这让解析变得很痛苦。

我可以检查 perl 的版本,或者只编写解析器来处理这两种情况,但某些东西告诉我一定有更好的自省(introspection)方法可用。

最佳答案

在 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涵盖从 C 调用 Perl 函数。我想出了以下未经测试的代码:

/* 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);

关于c - 如何在 Perl API 中内省(introspection)正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11851336/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com