首先,记得#include <regex>
。
C++ std::regex_match
与其他语言的正则表达式很像。
让我们先从一个简单的例子:
std::string str = "Mem(100)=120";
std::regex regex("^Mem\\([0-9]+\\)=[0-9]+$");
std::cout << std::regex_match(str, regex) << std::endl;
在这种情况下,我们的正则表达式是^Mem\([0-9]+\)=[0-9]+$
。 让我们来看看它做什么:
- 的
^
开头讲述C++,这是线开始的地方,所以应该AMem(1)=2
不匹配。
$
最后告诉C++这是行结束的地方,所以Mem(1)=2x
应该不匹配。
\\(
是一个文字(
字符。 (
在正则表达式中有一个非常特殊的含义,所以我们将其转义为\(
。但是,\
字符在C++字符串中有特殊含义,所以我们使用\\(
来告诉C++将\(
传递给正则表达式引擎。
[0-9]
符合数字。 \\d
也应该可以工作,但then again maybe not。
[0-9]+
表示至少一个数字。如果Mem()
是可以接受的,则改为使用[0-9]*
。
正如您所见,这就像您在其他语言(如Java或C#)中找到的正则表达式一样。
现在要考虑的空白,使用std::regex regex("^\\s*Mem\\([0-9]+\\)\\s*=\\s*[0-9]+\\s*$");
注意\s
包括\t
,因此无需同时指定。如果没有,请使用(\s|\t)
或[\s\t]
,而不是(\s,\t)
。
最后,要包含浮点数,我们首先需要考虑是否可以接受Mem(1) = 1.
(也就是后面没有数字的点)。
如果不是,则中的.23
是可选。在正则表达式中,我们使用?
来表示。
std::regex regex("^[\\s]*Mem\\([0-9]+\\)\\s*=\\s*[0-9]+(\\.[0-9]+)?\\s*$");
注意,我们使用\.
,而不只是.
。 .
在正则表达式中有特殊含义 - 它匹配任何字符 - 所以我们需要逃避它。
如果您有支持原始字符串编译器(如Visual Studio 2013,GCC 4.5,Clang 3.0),可以简化正则表达式的字符串:
std::regex regex(R"(^[\s]*Mem\([0-9]+\)\s*=\s*[0-9]+(\.[0-9]+)?\s*$)")
提取有关匹配字符串的信息,您可以使用std::smatch
和团体。
让我们先从一个小的变化:
std::string str = " Mem(100)=120";
std::regex regex("^[\\s]*Mem\\(([0-9]+)\\)\\s*=\\s*([0-9]+(\\.[0-9]+)?)\\s*$");
std::smatch m;
std::cout << std::regex_match(str, m, regex) << std::endl;
注意三件事情:
- 我们加入
smatch
。这个类存储关于匹配的额外结果信息。
- 我们在
[0-9]*
附近添加了附加括号。这定义了一个组。组告诉正则表达式引擎跟踪其中的任何内容。
- 围绕浮点数的更多括号。这定义了第二组。
非常重要定义组的括号内没有逃过,因为我们不想让他们来匹配实际括号字符。我们实际上需要特殊的正则表达式的含义。
现在我们有了群体,我们可以使用它们:
for (auto result : m) {
std::cout << result << std::endl;
}
这将首先打印整个字符串,然后将数Mem()
,那么最后的数字。
换句话说,m[0]
给我们整场比赛,m[1]
给我们的第一组,m[2]
给了我们第二组和m[3]
会给我们第三组,如果我们有一个。
我不太明白这个问题。如果你想知道如何在C++中使用正则表达式,那里有很多例子。顺便说一下,你可能应该跳过你的括号 - '... Mem \([0-9] * \)...'。 – Dukeling
@Dukeeling,这就是我在这里问的原因。我既没有找到类似的例子,也没有弄清楚正则表达式模式匹配是如何工作的。 –
正则表达式对于这样一个简单的模式是矫枉过正的。将行读入字符串,搜索'(',搜索')',搜索下一个数字。 –