使用regex.h进行全词匹配
Whole-word matching with regex.h
我想要一个C++正则表达式,它匹配"香蕉"或"睡衣",但不匹配"bananas2"、"bananas睡衣"或"香蕉",或者基本上除了这两个词之外的任何词。所以我做了这个:
#include <regex.h>
#include <stdio.h>
int main()
{
regex_t rexp;
int rv = regcomp(&rexp, "\bbananas\b|\bpajamas\b", REG_EXTENDED | REG_NOSUB);
if (rv != 0) {
printf("Abandon hope, all ye who enter heren");
}
regmatch_t match;
int diditmatch = regexec(&rexp, "bananas", 1, &match, 0);
printf("%d %dn", diditmatch, REG_NOMATCH);
}
并且它打印CCD_ 1,就好像没有匹配一样。发生了什么?我还为正则表达式尝试了bbananasb|bpajamasb
,但也失败了。
我用regex询问了关于std::regex的全词匹配,但std::regx很糟糕,速度很慢,所以我正在尝试regex.h。
POSIX标准既没有为BRE和ERE指定单词边界语法,也没有为其指定look-behind-and-look-ahead语法(可用于模拟单词边界)。因此,不可能编写一个具有单词边界的regex,它可以在不同的POSIX兼容平台上工作。
对于可移植的解决方案,如果您计划使用C++进行编码,则应该考虑使用PCRE或Boost.Regex。
否则,您将使用不可移植的解决方案。如果你可以接受这样的限制,有几个替代方案:
- 如果你链接到GNU C库,它会扩展语法以包括单词边界,以及其他内容:
b
(单词边界)、B
(非单词边界),<
(单词的开头)、>
(单词的结尾) - 一些系统将BRE和ERE语法扩展为包括
[[:<:]]
(单词的开头)、[[:>:]]
(单词的结尾)语法
Konrad留下了一个很好的答案,解决了我的问题,但它不知怎么消失了,所以我无法接受。以下是为子孙后代打印正确内容的代码:
#include <regex.h>
#include <stdio.h>
int main()
{
regex_t rexp;
int rv = regcomp(&rexp, "[[:<:]]bananas[[:>:]]|[[:<:]]pajamas[[:>:]]", REG_EXTENDED | REG_NOSUB);
if (rv != 0) {
printf("Abandon hope, all ye who enter heren");
}
regmatch_t match;
int diditmatch = regexec(&rexp, "bananas", 1, &match, 0);
printf("%d %dn", diditmatch, REG_NOMATCH);
}
使用
s == "balances" || s == "pajamas"
而其中CCD_ 10是CCD_。
正则表达式可能会使简单的解决方案过于复杂。如果你想要固定的匹配,尤其要避免它们。
相关文章:
- C++ std::regex 使用前瞻失败
- 使用 boost::regex 从目录中获取带有一些正则表达式的文件名称时出现意外输出
- 使用Regex解析cpp中的字符串并创建映射
- 在C++中使用带有regex的捕获组
- 使用 boost::regex (c++) 比较两个正则表达式
- 包含在 std::regex 搜索中,使用 std::regex_token_iterator 从 std::sub_m
- 使用REGEX进行电子邮件输入验证C
- 使用 std::regex 拆分一行并丢弃空元素
- 尝试使用生成文件编译程序时"fatal error: boost/regex.hpp: No such file or directory" C++
- 使用REGEX以UTF8格式过滤字符串
- 在Regex CPP中使用变量
- 使用Regex搜索评论的代码
- 使用Regex验证电子邮件和电话字段QT
- 使用Boost或Regex拆分这条线
- MongoDB C驱动程序:如何使用Regex查询集合
- 使用Regex过滤错误的输入
- 使用clang编译时regex-segfault,可能存在编译器错误
- 使用regex进行条件组匹配
- Regex:对非常数字符串使用smatch
- 使用std::regex替换前导空格和尾随空格