「Linux C 正则表达式」——用 C 语言优雅处理字符串

1. 前言

在 C 语言中,处理字符串是一项非常重要的工作。而正则表达式可以帮助我们更加优雅的处理字符串。本文将介绍如何在 Linux C 中使用正则表达式来处理字符串。文章从什么是正则表达式开始,逐步引入 C 语言中正则表达式的使用方法,介绍了常见的正则表达式匹配函数。

2. 正则表达式简介

2.1 什么是正则表达式

正则表达式是一种字符串匹配模式,用于检索文本中符合给定模式的字符串。可以通过使用正则表达式来执行搜索、替换等操作。

正则表达式是由特殊字符和普通字符组成的表达式,特殊字符具有特殊的含义,用于表示一类字符,而普通字符则表示单个字符。例如,字符类 [] 匹配其中任意一个字符,量词符 * 表示匹配前面的字符出现 0 次或多次。

2.2 正则表达式常用语法

下表列举了正则表达式中常用的语法:

语法 描述
. 匹配任意单个字符,除了换行符和行结束符
[...] 匹配方括号中的任意单个字符
[^...] 匹配不在方括号中的任意单个字符
^ 匹配字符串开始位置
$ 匹配字符串结束位置
* 匹配前面的字符出现零次或多次
+ 匹配前面的字符出现一次或多次
? 匹配前面的字符出现零次或一次
{n} 匹配前面的字符恰好出现 n 次
{n, m} 匹配前面的字符至少出现 n 次,至多出现 m 次
(...) 匹配圆括号中的任意表达式,并将其作为一个分组
| 匹配 | 左侧或右侧的任意表达式
\ 用于转义特殊字符

2.3 正则表达式实例

下表列举了一些常用的正则表达式实例:

正则表达式 描述
^[a-z]+$ 匹配只包含小写字母的字符串
^(http:\/\/|https:\/\/)[a-zA-Z0-9]+\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$ 匹配以 http:// 或 https:// 开头,中间有一个或多个字母数字字符,以 . 分隔,以字母数字字符结束的字符串
^\d{3}-\d{2}-\d{4}$ 匹配美国的社会安全号码格式:###-##-####

3. Linux C 中的正则表达式

3.1 regex.h 头文件

C 语言的正则表达式库在头文件 regex.h 中。该库提供了多个函数,可用于处理正则表达式匹配。

3.2 正则表达式匹配函数

下面是 regex.h 中常用的正则表达式匹配函数:

regcomp()

regexec()

regerror()

regfree()

regcomp() 函数用于编译正则表达式为一个内部格式,以便后续使用。regexec() 函数用于执行匹配操作。如果一个字符串匹配了正则表达式,那么 regexec() 函数将返回 0,否则将返回一个非零值。regerror() 函数用于打印关于错误的信息。regfree() 函数用于释放由 regcomp() 函数分配的内存。

4. 示例代码

4.1 匹配 IP 地址

下面的代码演示了如何使用正则表达式匹配 IP 地址:

#include <stdio.h>

#include <stdlib.h>

#include <regex.h>

int main()

{

char *str = "192.168.1.1";

regex_t regex;

int reti;

char msgbuf[100];

// 编译正则表达式

reti = regcomp(&regex, "^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$", 0);

if (reti) {

fprintf(stderr, "Could not compile regex\n");

exit(1);

}

// 执行匹配操作

reti = regexec(&regex, str, 0, NULL, 0);

if (!reti) {

printf("%s is a valid IP address\n", str);

} else if (reti == REG_NOMATCH) {

printf("%s is not a valid IP address\n", str);

} else {

regerror(reti, &regex, msgbuf, sizeof(msgbuf));

fprintf(stderr, "Regex match failed: %s\n", msgbuf);

exit(1);

}

// 释放内存

regfree(&regex);

return 0;

}

该代码使用正则表达式 ^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$ 匹配一个 IP 地址。其中,\\d 表示一个数字字符,{n,m} 表示前面的字符出现 n 次到 m 次。这个正则表达式可以匹配类似 192.168.1.1 这样的 IP 地址,而不能匹配例如 192.168.01.1 这样的非法 IP 地址。

4.2 匹配手机号码

下面的代码演示了如何使用正则表达式匹配手机号码:

#include <stdio.h>

#include <stdlib.h>

#include <regex.h>

int main()

{

char *str = "13001234567";

regex_t regex;

int reti;

char msgbuf[100];

// 编译正则表达式

reti = regcomp(&regex, "^(1[3456789]\\d{9})$", 0);

if (reti) {

fprintf(stderr, "Could not compile regex\n");

exit(1);

}

// 执行匹配操作

reti = regexec(&regex, str, 0, NULL, 0);

if (!reti) {

printf("%s is a valid phone number\n", str);

} else if (reti == REG_NOMATCH) {

printf("%s is not a valid phone number\n", str);

} else {

regerror(reti, &regex, msgbuf, sizeof(msgbuf));

fprintf(stderr, "Regex match failed: %s\n", msgbuf);

exit(1);

}

// 释放内存

regfree(&regex);

return 0;

}

该代码使用正则表达式 ^(1[3456789]\\d{9})$ 匹配一个手机号码。其中,1[3456789] 表示手机号码的前三位是 13、14、15、16、17、18 或 19。\\d 表示任意一个数字字符,{9} 表示前面的字符出现 9 次。这个正则表达式可以匹配类似 13001234567 这样的手机号码,而不能匹配例如 12000123456 这种非法手机号码。

4.3 匹配邮箱地址

下面的代码演示了如何使用正则表达式匹配邮箱地址:

#include <stdio.h>

#include <stdlib.h>

#include <regex.h>

int main()

{

char *str = "john.doe@gmail.com";

regex_t regex;

int reti;

char msgbuf[100];

// 编译正则表达式

reti = regcomp(&regex, "^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$", 0);

if (reti) {

fprintf(stderr, "Could not compile regex\n");

exit(1);

}

// 执行匹配操作

reti = regexec(&regex, str, 0, NULL, 0);

if (!reti) {

printf("%s is a valid email address\n", str);

} else if (reti == REG_NOMATCH) {

printf("%s is not a valid email address\n", str);

} else {

regerror(reti, &regex, msgbuf, sizeof(msgbuf));

fprintf(stderr, "Regex match failed: %s\n", msgbuf);

exit(1);

}

// 释放内存

regfree(&regex);

return 0;

}

该代码使用正则表达式 ^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$ 匹配一个邮箱地址。其中,[a-zA-Z0-9._%+-] 匹配任意一个字母、数字、点、下划线、百分号、加号、减号。@[a-zA-Z0-9.-]+ 匹配一个 @ 符号,后面跟着一个或多个字母、数字、点、减号。最后的[a-zA-Z]{2,} 匹配任意两个或以上的字母。这个正则表达式可以匹配类似 john.doe@gmail.com 这样的邮箱地址。

5. 总结

Linux C 语言提供了内置的正则表达式库来帮助处理字符串。通过使用正则表达式,我们可以更加优雅地处理字符串,进行搜索、替换等操作。在本文中,我们首先介绍了正则表达式的基本知识,包括正则表达式的语法和实例。然后,我们介绍了 Linux C 中的正则表达式库 regex.h,以及常用的正则表达式匹配函数。最后,我们通过示例代码演示了如何使用正则表达式匹配 IP 地址、手机号码、邮箱地址。希望读者在学习本文后,能够更好地应用正则表达式来处理字符串。

操作系统标签