我有一个带有一个C ++函数名的平面文件,其部分声明如下:
virtual void NameSpace1::NameSpace2::ClassName1::function_name1(int arg1) const
void function_name2
void NameSpace2::NameSpace4::ClassName2::function_name3
function_name4
我试图通过使用以下行来单独提取函数名称:
fn_name = re.match(":(.*?)\(?", lines)
我可以理解为什么function_name2
和function_name4
不匹配(因为没有前导:
。但即使对于function_name1
和{{1}我也看到了},它不进行非贪婪的匹配。function_name3
的输出是
fn_name.group()
我有三个问题:
:NameSpace2::ClassName1::function_name1
"要从第1行中提取,但非贪婪的匹配似乎不起作用。为什么?请帮忙。
答案 0 :(得分:3)
1)始终使用r" "
字符串表示正则表达式。
2)
我试图通过使用以下行来单独提取函数名称:
fn_name = re.match(":(.*?)\(?", lines)
fn_name.group()的输出是
:NameSpace2::ClassName1::function_name1
我没有看到:
import re
line = "virtual void NameSpace1::NameSpace2::ClassName1::function_name1(int arg1) const"
fn_name = re.search(r":(.*?)\(?", line)
print(fn_name.group())
--output:--
:
无论如何,如果你想看看非贪婪是如何运作的,请看这段代码:
import re
line = "N----1----2"
greedy_pattern = r"""
N
.*
\d
"""
match_obj = re.search(greedy_pattern, line, flags=re.X)
print(match_obj.group())
non_greedy_pattern = r"""
N
.*?
\d
"""
match_obj = re.search(non_greedy_pattern, line, flags=re.X)
print(match_obj.group())
--output:--
N----1----2
N----1
非贪婪的版本要求所有匹配.*
的字符直到遇到的第一个数字,而贪婪的版本将尝试找到.*
的最长匹配,然后是数字。
3)警告!没有正则表达式区域!
func_names = [
"virtual void NameSpace1::NameSpace2::ClassName1::function_name1(int arg1) const",
"void function_name2",
"void NameSpace2::NameSpace4::ClassName2::function_name3",
"function_name4",
]
for func_name in func_names:
name = func_name.rsplit("::", 1)[-1]
pieces = name.rsplit(" ", 1)
if pieces[-1] == "const":
name = pieces[-2]
else:
name = pieces[-1]
name = name.split('(', 1)[0]
print(name)
--output:--
function_name1
function_name2
function_name3
function_name4
答案 1 :(得分:3)
这很有效,至少以你的例子为准:
^(?:\w+ +)*(?:\w+::)*(\w+)
即,在Python代码中:
import re
function_name = re.compile(r'^(?:\w+ +)*(?:\w+::)*(\w+)', re.MULTILINE)
matches = function_name.findall(your_txt)
# -> ['function_name1', 'function_name2', 'function_name3', 'function_name4']
外卖:如果你能用贪婪的匹配来做,那就用贪婪的匹配来做。
请注意,对于C标识符,\w
不正确,但写下与此相匹配的技术上正确的字符类除了问题之外。查找并使用正确的字符集,而不是\w
。
答案 2 :(得分:1)
- 我希望从第1行中提取字符串“function_name1”,但非贪婪的匹配似乎不起作用。为什么?
醇>
这是您的正则表达式":(.*?)\(?"
的结果我认为你的正则表达是“Too Lazy”。它仅匹配:
,因为(.*?)
代表匹配任何字符“尽可能少”然后正则表达式引擎选择匹配零字符。它会在您预期的\(?
之前匹配,因为?
仅表示“可选”。
- 为什么第3行没有被提取?
醇>
我测试了你的正则表达式。它根本不起作用,不仅仅是第三行。
- 如何使用单个正则表达式从所有行获取函数名称?
醇>
你可以从这个最小的例子开始
(?:\:\:|void\s+)(\w+)(?:\(|$)|(function_name4)
(?:\:\:|void\s+)
代表任何领导您的函数名称的内容,(?:\(|$)
代表任何跟随您的函数名称的内容。
请注意,function_name4
假设由于缺少模式而被明确声明。
请参阅:DEMO
答案 3 :(得分:0)
我试图从“N foo bar N ---- 1 ---- 2”中捕获“N ---- 1”时被类似的东西所困扰。添加一个前导。*给出了所需的结果。
import re
line = "N foo bar N----1----2"
match_obj = re.search(r'(N.*?\d)', line)
print(match_obj.group(1))
match_obj = re.search(r'.*(N.*?\d)', line)
print(match_obj.group(1))
--output:--
N foo bar N----1
N----1