在 C++ 中使用正则表达式检查字符串

Posted

技术标签:

【中文标题】在 C++ 中使用正则表达式检查字符串【英文标题】:Checking strings with regex in C++ 【发布时间】:2012-06-25 07:41:33 【问题描述】:

我将在 C++ 应用程序中使用正则表达式,但我没有使用正则表达式的经验。我特别想检查一些字符串是否属于以下类别之一:

X.anystring -> X 必须是唯一且唯一的字母(不是数字)。

XY.anystring -> X, Y 必须是数字 0-9(不是字母)。

如何使用正则表达式检查它们?为了让我熟悉正则表达式,您可以推荐什么正则表达式教程?

【问题讨论】:

您查看过 cppreference.com 吗? 看看Boost Regex。 这个问题的两个答案如何相互补充很有趣。一个是关于正则表达式的,另一个是关于 C++ 库的。 【参考方案1】:

说真的,在这种情况下,regexp:s 不是适合您的解决方案。

首先,regexp:s 不是 C++ 语言的一部分,因此您需要使用特定的 regexp 库。 (C++11 包括对 regexp:s 的支持。)

其次,您的两个用例都可以简单地用纯 C++ 编码,您需要做的就是遍历字符串中的字符并检查它们是否符合您的要求。

【讨论】:

说实话,他甚至不需要循环;他从不需要看三个以上的字符。但这对于让他开始使用正则表达式可能是一个很好的练习,并且在处理文本输入时,您很快就会发现正则表达式是最简单的解决方案。 为什么他不需要循环检查所有的表达式?【参考方案2】:

当前的 C++11 标准支持正则表达式,但我不确定哪些编译器支持它并准备好使用。

与此同时,Boost 库为 C++ (link here) 提供了一个不错的正则表达式系统。

在学习正则表达式方面,this 可能会有所帮助(专注于使用 Boost 正则表达式)。

对于您的情况可能更简单的替代解决方案是您自己编写代码。比如:

bool check_first(const string& myString)

    if (!isalpha(myString[0]) || myString[1] != '.') return false;
    return true;


bool check_second(const string& myString)

    if (!isdigit(myString[0]) || !isdigit(myString[1]) || myString[2] != '.') return false;
    return true;

【讨论】:

前两个陈述在形式上相互矛盾,因为当前的 C++ 标准 C++11。 (当然,在实践中,能不能真正使用是另外一回事。但是标准的正则表达式是基于boost的,所以可以使用。)【参考方案3】:

X.anystring -> X 必须是唯一且唯一的字母(不是 位)。

需要的正则表达式是

[a-zA-Z]\.[\w]+

XY.anystring -> X, Y 必须是数字 0-9 (不是字母)。

需要的正则表达式是

[0-9]2\.[\w]+

详细了解正则表达式here。一旦您大致了解了正则表达式,您就可以应用到您选择的任何语言。

【讨论】:

我认为这些都不对。首先,第一个不匹配所有字母字符。 \b 的目的是什么?而[] 中的\w? (我不认为\w实际上是在[]中定义的;它通常定义为[^_[:alnum:]],这在[]中是不合法的。) 我忽略了 alpha 字符,因为 OP 特别提到了 letter\w 确实允许在 [] 内部,尽管它不是 POSIX 标准。而\b 我同意在这种情况下是多余的。我编辑了\b 您能否指出\w[] 中允许的位置(以及哪个版本的正则表达式---有很多)。 C++11 似乎不太清楚:它要么是被禁止的(未定义的行为,因为未指定),要么是(我的阅读,虽然我完全不确定这是不是意图)相当于[[_[:alnum:]]],其中,当后跟+ 时,将匹配[_ 或alnum,后跟一个或多个]。 (鉴于 OP 说“任何字符串”,而不是符号,.* 无论如何都是想要的。) 另外:à 是一个字母,但不会被 [a-zA-Z] 匹配。 \w 已经是一个字符类。它不需要被包裹在一个。在这种情况下,这是错误的——你应该使用.*,因为它应该匹配 any 字符串,而不仅仅是单词。【参考方案4】:

如果你只是想知道一个字符串是否匹配一个或另一个,但你不在乎它匹配哪个,你可以使用:

"(?:(?:[a-zA-Z])|(?:[0-9]2))\..*"

使用 C++11 regexECMAScript 语法。

【讨论】:

【参考方案5】:
#include <regex>

std::string str = "OnlyLetter,12345";

std::string x = "([a-z]|[A-Z])+";
std::string y = "[0-9]+";
std::string expression = std::string(x).append(",").append(y);
std::tr1::regex rx(expression);
bool match = std::tr1::regex_match(str.c_str(),rx);
// match = true. Valid String
// match = false. Invalid String. ex.: "OnlyLetter,12s345"

【讨论】:

【参考方案6】:

这取决于您使用的正则表达式库。但是 以下应该适用于 Boost 和 C++11:

对于 X.anystring(X 为 alpha):

"[[:alpha:]]\\..*"

对于 XY.anystring:

"[[:digit:]][[:digit:]]\\..*"

这些用于regex_match;如果你想使用regex_search, 您必须将表达式“锚定”到字符串的开头 用'^'作为前缀(但你可以去掉最后的'.*')。

【讨论】:

以上是关于在 C++ 中使用正则表达式检查字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 的正则表达式中使用变量? [关闭]

使用正则表达式在 C++ 中提取匹配的字符串

在 C++ 中使用“DEFINED”子表达式组合复杂的正则表达式

用于匹配单词的 javascript 正则表达式模式,具有自定义单词边界

正则表达式检查字符串是不是只有空格

如何使用正则表达式从 C++ 字符串中提取字符串