匹配表达式,但不匹配以 # 开头的行



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

[().wd]+.set_name()s*

这就是我想要它做的

abc.set_name() // match
# abc.set_name() // don't match
xyz.set_name() // match and capture this one

更新以获得更多澄清:

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

Hellonx=y*2nabc.set_name()   n#xyz.set_name()

它是一个以n为换行符的长字符串。

更新:用于测试的较长测试字符串。我已经尝试了所有建议的正则表达式,但它们都不起作用。不知道缺了什么。https://regex101.com/r/vXpXIA/1

更新2:Scratch我的第一次更新,nqDebug(),在使用regex时不需要考虑它。

如果您只想匹配与模式匹配的最后一行

^[a-z]+.set_name()

可以使用正则表达式。

(?smi)^[a-z]+.set_name()(?!.*^[a-z]+.set_name())

为了简单起见,我使用了字符类[a-z]。可以根据需要进行更改。在这个问题中,它是[().wd],可以简化为[().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

回想一下,单行模式使.与换行符匹配,而多行模式使^$与行的开头和结尾(而不是字符串的开头和末尾(匹配。

您需要regex前瞻运算符(如果您的regex引擎支持(。这会奏效的。

(?(?=^[^#])(^s*[a-zA-Z]+.set_name())|z^)

解释:

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

  • patt=^[^#]-在线路开始时,没有#

  • 则部分-如果patt为true,则^s*[a-zA-Z]*.set_name()匹配后面跟有<something>.set_name()的任意数量的空白,其中something是变量名。

  • else-part-如果patt为false,则匹配行开始之前的z的z^,这是不可能的。


Edit:刚刚意识到变量名中可以有数字(但不能以数字开头(。在这种情况下,改进的regex(未测试(

(?(?=^[^#])(^s*[a-zA-Z]+[a-zA-Zd]*.set_name())|z^)

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

只需根据新行将字符串拆分即可。

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::istringstream isr;
isr.str("I am Johnn 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
}
}

您可以使用

(?s).*n(?!h*#)h*([w().]+.set_name())

请参阅regex演示,您的匹配项在第1组详细信息

  • (?s)-DOTALL模式打开,.现在匹配任何字符
  • .*-尽可能多的任何零个或多个字符
  • n(?!h*#)-一个换行符,后面没有0个或多个水平空白,然后是一个#字符
  • h*-0+水平空白
  • ([w().]+.set_name())-捕获组1:
    • [w().]+-1个或多个字字符,)(.
    • .set_name().set_name()字符串

相关内容

  • 没有找到相关文章

最新更新