我正在经过一些关于如何在ANSI C中使用正则表达式的简单示例和最佳实践。man regex.h
没有提供太多帮助。C中的正则表达式:例子?
127
A
回答
167
正则表达式实际上不是ANSI C的一部分。听起来好像你可能会谈论POSIX正则表达式库,它带有大多数(所有?)* nixes。这里是(基于this c)中使用POSIX正则表达式的例子:
#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
语法等
9
它可能不是你想要的,但像re2c的工具可以编译POSIX(-ish)正则表达式来ANSI C.它用作为替代对于lex
,但是如果你真的需要这种方法,你可以牺牲最后一点速度的灵活性和可读性。
3
man regex.h
报告没有用于regex.h的手动输入,但man 3 regex
为您提供了一个解释用于模式匹配的POSIX函数的页面。
在The GNU C Library: Regular Expression Matching中描述了相同的功能,其中解释了GNU C库支持POSIX.2接口以及GNU C库多年以来的接口。
例如,对于一个假想的程序,它作为参数传递的字符串匹配的模式作为第一个参数传递打印,你可以使用类似的代码下列之一:
#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\}
而不是extended regular expressions中使用的a{3}
,这可能是您期望使用的。
POSIX.2还有另一个通配符匹配功能:fnmatch()
。它不允许编译正则表达式,也不允许与子表达式匹配的子字符串,但是它非常具体地用于检查文件名与通配符匹配的时间(例如,它使用FNM_PATHNAME
标志)。
ANSI C中没有内置的正则表达式支持。您使用的是哪种正则表达式库? – Joe 2009-07-06 01:59:55
[Rob Pike](http://en.wikipedia.org/wiki/Rob_Pike)写了一个小型的正则表达式字符串搜索函数,该函数接受了一本非常有用的正则表达式子集,他编写了“编程实践”一书,他和[Brian Kernighan ](http://en.wikipedia.org/wiki/Brian_Kernighan)共同撰写。见Kernighan博士的这个讨论,一个正则表达式匹配器http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html – 2014-12-14 23:18:25