我在一些简单的例子和如何在 ANSI C 中使用正则表达式的最佳实践之后。man regex.h
没有提供那么多帮助。
正则表达式实际上不是 ANSI C 的一部分。听起来你可能在谈论 POSIX 正则表达式库,它附带了大多数 (所有?) * nix。下面是在 C 中使用 POSIX 正则表达式的示例 (基于this):
#include <regex.h>
regex_t regex;
int reti;
char msgbuf[100];
/* Compile regular expression */
reti = regcomp(®ex, "^a[[:alnum:]]", 0);
if (reti) {
fprintf(stderr, "Could not compile regex\n");
exit(1);
}
/* Execute regular expression */
reti = regexec(®ex, "abc", 0, NULL, 0);
if (!reti) {
puts("Match");
}
else if (reti == REG_NOMATCH) {
puts("No match");
}
else {
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
fprintf(stderr, "Regex match failed: %s\n", msgbuf);
exit(1);
}
/* Free memory allocated to the pattern buffer by regcomp() */
regfree(®ex);
或者,您可能需要查看PCRE,这是一个用于 C 中与 Perl 兼容的正则表达式的库。Perl 语法与 Java,Python 和许多其他语言中使用的语法几乎相同。POSIX 语法是grep
,sed
,vi
等使用的语法。
这可能不是你想要的,但是像re2c这样的工具可以将 POSIX(-ish)正则表达式编译为 ANSI C。它是作为lex
的替代品编写的,但是如果你真的需要它,这种方法可以让你为最后一点速度牺牲灵活性和易读性。

这是使用 REG_EXTENDED 的示例。此正则表达式
"^(-)?([0-9]+)((,|.)([0-9]+))?\n$"
允许您在西班牙语系统和国际中捕获十进制数。:)
#include <regex.h>
#include <stdlib.h>
#include <stdio.h>
regex_t regex;
int reti;
char msgbuf[100];
int main(int argc, char const *argv[])
{
while(1){
fgets( msgbuf, 100, stdin );
reti = regcomp(®ex, "^(-)?([0-9]+)((,|.)([0-9]+))?\n$", REG_EXTENDED);
if (reti) {
fprintf(stderr, "Could not compile regex\n");
exit(1);
}
/* Execute regular expression */
printf("%s\n", msgbuf);
reti = regexec(®ex, msgbuf, 0, NULL, 0);
if (!reti) {
puts("Match");
}
else if (reti == REG_NOMATCH) {
puts("No match");
}
else {
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
fprintf(stderr, "Regex match failed: %s\n", msgbuf);
exit(1);
}
/* Free memory allocated to the pattern buffer by regcomp() */
regfree(®ex);
}
}

man regex.h
没有显示 regex.h 的任何手动输入,但是man 3 regex
显示了一个页面,解释了用于模式匹配的 POSIX 函数。
The GNU C Library: Regular Expression Matching中描述了相同的函数,它解释了 GNU C 库支持 POSIX.2 接口和 GNUC 库多年来使用的接口。
例如,对于打印作为参数传递的字符串与作为第一个参数传递的模式匹配的假设程序,您可以使用类似于以下内容的代码。
#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_regerror (int errcode, size_t length, regex_t *compiled);
int
main (int argc, char *argv[])
{
regex_t regex;
int result;
if (argc < 3)
{
// The number of passed arguments is lower than the number of
// expected arguments.
fputs ("Missing command line arguments\n", stderr);
return EXIT_FAILURE;
}
result = regcomp (®ex, argv[1], REG_EXTENDED);
if (result)
{
// Any value different from 0 means it was not possible to
// compile the regular expression, either for memory problems
// or problems with the regular expression syntax.
if (result == REG_ESPACE)
fprintf (stderr, "%s\n", strerror(ENOMEM));
else
fputs ("Syntax error in the regular expression passed as first argument\n", stderr);
return EXIT_FAILURE;
}
for (int i = 2; i < argc; i++)
{
result = regexec (®ex, argv[i], 0, NULL, 0);
if (!result)
{
printf ("'%s' matches the regular expression\n", argv[i]);
}
else if (result == REG_NOMATCH)
{
printf ("'%s' doesn't the regular expression\n", argv[i]);
}
else
{
// The function returned an error; print the string
// describing it.
// Get the size of the buffer required for the error message.
size_t length = regerror (result, ®ex, NULL, 0);
print_regerror (result, length, ®ex);
return EXIT_FAILURE;
}
}
/* Free the memory allocated from regcomp(). */
regfree (®ex);
return EXIT_SUCCESS;
}
void
print_regerror (int errcode, size_t length, regex_t *compiled)
{
char buffer[length];
(void) regerror (errcode, compiled, buffer, length);
fprintf(stderr, "Regex match failed: %s\n", buffer);
}
regcomp()
的最后一个参数必须至少为REG_EXTENDED
,否则函数将使用basic regular expressions,这意味着(例如)您需要使用a\{3\}
而不是a{3}
从extended regular expressions使用,这可能是您期望使用的。
POSIX.2 还有另一个用于通配符匹配的函数:fnmatch()
它不允许编译正则表达式,或获取匹配子表达式的子字符串,但它非常具体地用于检查文件名何时匹配通配符(例如,它使用FNM_PATHNAME
标志)。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(40条)