C++中的QRegExp捕获部分字符串

QRegExp in C++ to capture part of string

我正在尝试使用 Qt 在我的 C++ 应用程序中执行正则表达式。 我以前在C++中用Qt做过类似的正则表达式,但是这个很难。

给定一个字符串,字符串末尾带有可选的 _#,我想提取字符串之前的部分。

示例:

"blue_dog" should result "blue_dog"
"blue_dog_1" should result "blue_dog"
"blue_dog_23" should result "blue_dog"

这是我目前的代码,但它还不能工作:

QString name = "blue_dog_23";
QRegExp rx("(.*?)(_\d+)?");    
rx.indexIn(name);
QString result = rx.cap(1);  

我什至在许多变体中尝试了以下附加选项,但没有成功。我上面的代码总是以 "":

结果
rx.setMinimal(TRUE);   
rx.setPatternSyntax(QRegExp::RegExp2);

以下解决方案应该会如您所愿!

^[^\s](?:(?!_\d*\n).)*/gm

基本上,这就是说匹配所有直到 _\d*\n,但不包括 _\d*\n。这里,_\d*\n 表示匹配 _ 字符,然后匹配任意数量的数字 \d* 直到到达新的行标记 \n?! 是否定前瞻,?: 是非捕获组。基本上,组合意味着 ?: 之后的序列是代表应该捕获的内容的非包含端点的组。

^[^\s] 告诉表达式从行首开始匹配,只要第一个字符不是白色 space.

/gm设置全局标志(允许返回多个匹配项)和多行标志(允许序列匹配超过一行。

有时不将所有内容打包到一个正则表达式中会更容易。在您的情况下,您可以将操作限制在现有 _# 后缀的情况下。否则结果为 name:

QString name = "blue_dog_23";
QRegExp rx("^(.*)(_\d+)$");
QString result = name;
if (rx.indexIn(name) == 0)
    result = rx.cap(1);

或者,您可以拆分最后一位并检查它是否为数字。一个紧凑的(但可能不是最可读的)解决方案:

QString name = "blue_dog_23";
int i = name.lastIndexOf('_');
bool isInt = false;
QString result = (i >= 0 && (name.mid(i+1).toInt(&isInt) || isInt)) ? name.left(i) : name;