C++ 匹配一个表达式,但不要';t匹配以a开头的行#

C++ 匹配一个表达式,但不要';t匹配以a开头的行#,c++,regex,qregularexpression,C++,Regex,Qregularexpression,我就是我们。我有一个文本字符串,专门查找函数调用xyz.set_name(),我想捕获此调用的最后一次出现,但如果包含它的行以开头,则将其否定。到目前为止,我得到了与函数调用匹配的正则表达式,但我不知道如何否定匹配的行,也不知道如何捕获最后一个匹配项,不知道为什么所有匹配项都放在一个捕获组中 [().\w\d]+.set_name\(\)\s* 这就是我想要它做的 abc.set_name() // match # abc.set_name() // don't match xyz.set_n

我就是我们。我有一个文本字符串,专门查找函数调用
xyz.set_name()
,我想捕获此调用的最后一次出现,但如果包含它的行以
开头,则将其否定。到目前为止,我得到了与函数调用匹配的正则表达式,但我不知道如何否定匹配的
行,也不知道如何捕获最后一个匹配项,不知道为什么所有匹配项都放在一个捕获组中

[().\w\d]+.set_name\(\)\s*
这就是我想要它做的

abc.set_name() // match
# abc.set_name() // don't match
xyz.set_name() // match and capture this one
更新以获得更多澄清:

当用qDebug打印出来时,我的文本是这样读的

Hello\nx=y*2\nabc.set_name()   \n#xyz.set_name()
这是一个长字符串,
\n
作为换行符

更新:用于测试的较长测试字符串。我尝试了所有建议的正则表达式,但都不起作用。不知道少了什么。


更新2:Scratch我的第一次更新,
\n
是一个
qDebug()
东西,在使用regex时不需要考虑它。

您需要regex lookahead操作符(如果您的regex引擎支持它)。这个


说明:

  • (?(?=patt)then | else)
    -Regex如果else构造,如果Regex匹配给定模式
    patt
    则匹配
    ,否则匹配
    else

  • patt
    =
    ^[^#]
    --在行首,没有

  • 然后部分-如果
    patt
    为真--
    ^\s*[a-zA-Z]*\.set\u name\(\)
    匹配任何数量的空格,后跟
    .set\u name()
    ,其中
    某物
    是变量名

  • else部分——如果
    patt
    为false——匹配
    z^
    哪个z在行首之前,这是不可能的


编辑:刚刚意识到变量名中可以有数字(但不能以一开头)。在这种情况下,改进的正则表达式(未测试)


编辑:由于字符串中还有换行符,因此与问题中的问题描述不匹配。尽管如此,只需标记字符串就足够简单了

根据新行将字符串拆分

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

int main()
{
    std::istringstream isr;
    isr.str("I am John\n today is  \n#abc.set_name()\n");
    std::string tok;
    std::vector<std::string> vs;
    while(std::getline(isr, tok))
    {
        std::cout << tok << std::endl;
        vs.push_back(tok);
    }
    
    for (auto r_it = vs.rbegin(); r_it != vs.rend(); ++r_it)
    {
        std::cout << *r_it << std::endl;
        // if match then break from loop
    }
}


#包括
#包括
#包括
#包括
int main()
{
std::istringstream isr;
isr.str(“我是John\n今天是abc.set\u name()\n”);
std::字符串tok;
std::向量vs;
while(std::getline(isr,tok))
{

如果只想匹配与模式匹配的最后一行,则std::cout

^[a-z]+\.set_name\(\)
您可以使用正则表达式

(?smi)^[a-z]+\.set_name\(\)(?!.*^[a-z]+\.set_name\(\))
为了简单起见,我使用了字符类
[a-z]
。可以根据需要进行更改。在问题中,它是
[()。\w\d]
,可以简化为
[()。\w]

请注意,由于要匹配感兴趣的子字符串,因此也没有必要捕获它。最后一行之前的一行以
“#”
开头这一事实并不相关。重要的是这些行是否匹配指定的模式

PCRE正则表达式引擎执行以下操作

(?smi)                  : set single-line, multi-line and case-indifferent
                          modes  
^                       : match the beginning of a line
[a-z]+\.set_name\(\)    : match 1+ chars in the char class, followed
                          by '.set_name\(\)'
(?!                     : begin negative-lookahead
.*^[a-z]+\.set_name\(\) : match 0+ chars (including newlines), the  
                          beginning of a line, 1+ letters, '\.set_name\(\)' 
)                       : end negative lookahead
回想一下,单行模式使
匹配换行符,多行模式使
^
$
匹配行的开头和结尾(而不是字符串的开头和结尾)。

您可以使用

(?s).*\n(?!\h*#)\h*([\w().]+\.set_name\(\))
请参阅,您的对手在第1组。详细信息

  • (?s)
    -DOTALL模式打开,
    现在匹配任何字符
  • *
    -尽可能多的零个或多个字符
  • \n(?!\h*#)
    -换行符后面不紧跟0个或多个水平空格,然后是
    字符
  • \h*
    -0+水平空白
  • ([\w().]+\.设置名称\(\)
    -捕获组1:
    • [\w().]+
      -1个或多个单词字符,
    • \.set\u name\(\)
      -a
      .set\u name()
      字符串

您的示例显示了匹配但未捕获的第一行和匹配并捕获的最后一行。我不明白您的意思。请使用
(?s)。*\n(?!\h*)\h*([\w()。]+\.设置名称\(\)
,请参阅我的第一条评论,您只能匹配一个子字符串。您不能匹配由不匹配的子字符串分隔的两个子字符串。在三行示例中,您可以匹配所有三行(整个字符串)并捕获最后一行或仅匹配最后一行,在这种情况下,捕获它也没有意义。嗨,我的文本字符串是整个文本的一个长字符串,
\n
作为换行符。您的正则表达式找不到任何匹配项。直到负前瞻。很好!reddy,我在回答中的链接中使用的文本是
abc.set\u name()\n#abc.set_name()\nxyz.set_name()\n
,正如您所看到的,
xyz.set_name()
与正则表达式匹配。我不明白,如果您使用相同的测试字符串,为什么不会得到相同的结果。@CarySwoveland嗨,我用一个更长的字符串更新了第一篇文章以进行测试,谢谢。我还被qDebug()弄糊涂了我想我必须考虑到这一点。
(?smi)^[()。\w]+\.设置名称(\)(?!.^[()。\w]+\.设置名称(\)
。我会更新第一篇帖子,以免混淆未来的人。嗨,我的文本字符串在用qDebug打印时是这样读的:
我是约翰,今天是abc.设置名称()\n
,以
\n
作为换行符。您的正则表达式没有返回任何匹配项。请选中edit@reddy。它也不应该匹配对吗?因为
?是的,不匹配以
开头的行。我忘了您想要最后一个匹配项。进行了编辑。您好,这与字符串不匹配,只匹配
abc。set\u name()
Hi我已经用更长的测试字符串更新了第一篇文章,请看一看look@reddy好的,所以它可能是第一行,然后使用或
(?smi)                  : set single-line, multi-line and case-indifferent
                          modes  
^                       : match the beginning of a line
[a-z]+\.set_name\(\)    : match 1+ chars in the char class, followed
                          by '.set_name\(\)'
(?!                     : begin negative-lookahead
.*^[a-z]+\.set_name\(\) : match 0+ chars (including newlines), the  
                          beginning of a line, 1+ letters, '\.set_name\(\)' 
)                       : end negative lookahead
(?s).*\n(?!\h*#)\h*([\w().]+\.set_name\(\))