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\(\))