C语言中如何检测字符串含指定子串及引号间任意文本?
原代码使用strstr仅能匹配空引号的固定子串,无法满足“引号中间存在任意非空文本”的需求。以下提供两种可行的实现方案:
方法1:纯标准库实现(无额外依赖)
通过分步查找并验证的方式实现需求,无需引入外部库,兼容性强:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "../include/ANSI-color-codes.h" #define BUTTON_PREFIX "<button('" #define BUTTON_SUFFIX "') />" int main(int argc, char* const argv[]) { if (argc != 2) { printf(BLU "VPWL (Very Powerful Web Language) \nyou build big bundle Small\n" reset); return 1; } FILE *fptr = fopen(argv[1], "r"); if (!fptr) { // 增加文件打开失败的错误处理 perror("Failed to open file"); return 1; } char FileString[2097152]; // 2 MB 缓冲区 const size_t prefix_len = strlen(BUTTON_PREFIX); const size_t suffix_len = strlen(BUTTON_SUFFIX); while (fgets(FileString, sizeof(FileString), fptr)) { printf("%s", FileString); char *match_start = strstr(FileString, BUTTON_PREFIX); // 处理一行内多个匹配的情况 while (match_start != NULL) { char *content_start = match_start + prefix_len; char *match_end = strstr(content_start, BUTTON_SUFFIX); if (match_end != NULL && content_start < match_end) { // 匹配成功:引号中间存在非空内容 printf(RED "Valid button content: %.*s\n" reset, (int)(match_end - content_start), content_start); // 在此添加你的业务处理逻辑 } // 移动指针,查找下一个潜在匹配 match_start = strstr( match_end ? match_end + suffix_len : content_start, BUTTON_PREFIX ); } } fclose(fptr); return 0; }
关键逻辑说明
- 用常量定义前缀和后缀,避免硬编码重复字符串
- 先定位
<button('的起始位置,再跳转到第一个引号后的内容起始点 - 查找对应的
') />后缀,若存在且内容起始点早于后缀位置,说明中间有有效文本 - 循环处理一行内的多个匹配,避免遗漏
方法2:使用POSIX正则表达式(更简洁)
如果你的环境支持POSIX正则(大部分Linux/Unix系统默认支持),可以用正则表达式直接匹配模式,代码更简洁易维护。正则表达式<button\('([^']+)'\) />会匹配:
- 固定前缀
<button(' - 至少一个非引号字符(
[^']+,确保引号中间非空) - 固定后缀
') />
代码示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <regex.h> #include "../include/ANSI-color-codes.h" int main(int argc, char* const argv[]) { if (argc != 2) { printf(BLU "VPWL (Very Powerful Web Language) \nyou build big bundle Small\n" reset); return 1; } FILE *fptr = fopen(argv[1], "r"); if (!fptr) { perror("Failed to open file"); return 1; } // 编译正则表达式 regex_t regex; int reti = regcomp(®ex, "<button\\('([^']+)'\\) />", REG_EXTENDED); if (reti) { fprintf(stderr, "Could not compile regex\n"); return 1; } char FileString[2097152]; while (fgets(FileString, sizeof(FileString), fptr)) { printf("%s", FileString); reti = regexec(®ex, FileString, 0, NULL, 0); if (!reti) { // 匹配成功 printf(RED "Valid button found in line\n" reset); // 添加你的业务处理逻辑 } else if (reti != REG_NOMATCH) { // 处理正则匹配错误 char errbuf[100]; regerror(reti, ®ex, errbuf, sizeof(errbuf)); fprintf(stderr, "Regex error: %s\n", errbuf); } } regfree(®ex); fclose(fptr); return 0; }
编译注意事项
编译时需要链接正则库,使用以下命令:
gcc your_code.c -o your_program -lregex
通用注意事项
fgets会保留换行符,但不影响字符串匹配逻辑- 2MB缓冲区足够处理绝大多数文本行,若需支持更长行可考虑动态分配内存
- 两种方案均支持一行内多个匹配的场景
内容的提问来源于stack exchange,提问作者Same
相关产品推荐
相关产品推荐

