Python 使用正则表达式从c源获取函数调用的第二个字符串参数
我正在尝试解析SQLite源代码中的错误消息,我认为我目前的方法涵盖了大多数情况 我的正则表达式:Python 使用正则表达式从c源获取函数调用的第二个字符串参数,python,python-3.x,regex,Python,Python 3.x,Regex,我正在尝试解析SQLite源代码中的错误消息,我认为我目前的方法涵盖了大多数情况 我的正则表达式: (?:sqlite3ErrorMsg|sqlite3MPrintf|sqlite3VdbeError)\([^;\"]+\"([^)]+)\"(?:,|\)|:) 源代码段(无效的C,仅用于演示): 但是,由于(),它错过了函数%.*s()的错误数量的参数 我还尝试过从“捕获到”,并对其进行反向查看,以允许转义的\“(不要跳过no\”这样的“函数:%.*s),但我
(?:sqlite3ErrorMsg|sqlite3MPrintf|sqlite3VdbeError)\([^;\"]+\"([^)]+)\"(?:,|\)|:)
源代码段(无效的C,仅用于演示):
但是,由于()
,它错过了函数%.*s()的错误数量的参数
我还尝试过从“
捕获到”
,并对其进行反向查看,以允许转义的\“
(不要跳过no\”这样的“函数:%.*s
),但我无法让它工作,因为我的regex-foo没有那么强,而且还有多行字符串的情况
我还尝试将来自的答案与我的正则表达式结合起来,但这对我也不起作用
一般的想法是:
有一个函数调用,其中有三个提到的函数名(sqlite3ErrorMsg | sqlite3MPrintf | sqlite3VdbeError),后面是一个我不感兴趣的非字符串参数,后面至少有一个参数可能是变量(我不想要)或字符串(这就是我要找的!),后跟任意数量的可选参数
我想要的字符串可以是多行字符串,也可以包含转义引号、圆括号以及C字符串中允许的任何其他内容
我使用Python 3.7
你可以考虑以下模式:
(?:sqlite3ErrorMsg | sqlite3MPrintf | sqlite3VdbeError)\s*\(\s*\w+,((?:\s*“[^”\]*(?:\.^“\]*)*)+)
请参阅。您需要从匹配中的每一行手动删除分隔双引号
详细信息:
(?:sqlite3ErrorMsg | sqlite3MPrintf | sqlite3VdbeError)
-三个子字符串之一
\s*\(\s*
-a(
用零个或多个空格括起来的字符
\w+
-一个或多个单词字符
,
-逗号
((?:\s*”[^“\\]*(?:\\.^“\]*)*”)+
-第1组:一次或多次重复
\s*
-零个或多个空格
“
-a”
[^“\\]*
-除\
和“
之外,零个或多个字符
(?:\\.-.^“\\]*)*
-一个\
的零次或多次重复,然后任何字符后跟除和\
以外的零次或多次字符
“
-一个”
字符
样本:
重新导入
file=“sqlite3ErrorMsg(pParse,variable);\n sqlite3ErrorMsg(pParse,\“row value misused\”);\n{\n sqlite3ErrorMsg(pParse,\“no\\\”这样的\\\\“函数:%.*s\”,nId,zId);\n pNC->nErr++\n}如果(错误的参数数){\n sqlite3ErrorMsg(pParse,\“函数的参数数错误”%.*s(),\n nId,zId);\n pNC->nErr++;\n}\n if(pExpr->iTablenErr++;\n}\n}\n}else if(错误的参数){\n sqlite3ErrorMsg(pParse,\“工厂必须返回光标,而不是\\\\w+\”,\n nId);\n pNC->nErr++”
rx=r'(?:sqlite3ErrorMsg | sqlite3MPrintf | sqlite3VdbeError)\s*\(\s*\w+,((?:\s*“[^”\]*(?:\.[^”\]*)+)
为re.findall(rx,文件)中的m匹配=[“”.join(映射(lambda x:x.strip(“”),m.strip().splitlines()))
打印(匹配)
输出:
['row value misused', 'no \\"such\\" function: %.*s', 'wrong number of arguments to function %.*s()', 'second argument to likelihood must be a constant between 0.0 and 1.0', 'factory must return a cursor, not \\\\w+']
试试(?:sqlite3ErrorMsg | sqlite3MPrintf | sqlite3VdbeError)\s*(\s*\w+,((?:\s*“[^”\]*(?:\.[^“\]*)*”)
,看@WiktorStribiżew wow,这很快,效果几乎完美。你能把引号移出捕获组并作为答案发布吗?引号必须“手动”删除,否则,您将无法匹配多行字符串,就像您在“似然度的第二个参数必须是一个介于0.0和1.0之间的”“常数”
@WiktorStribiżew好的,没问题,strip(“”)
应该去掉它们。(编辑:strip没有按照我的要求工作,仍然没有问题,我可以从那里处理它)。我稍微更改了正则表达式,并将\w+
替换为[^,]+
,因为有时第一个参数可能是&sParse
或Parse->someValue
。我使用了strip()[1:-1]
,而不是strip(“)
,因为字符串本身可能以转义引号结尾。再次感谢!
row value misused
no \"such\" function: %.*s
second argument to likelihood must be a "
"constant between 0.0 and 1.0
factory must return a cursor, not \\w+
['row value misused', 'no \\"such\\" function: %.*s', 'wrong number of arguments to function %.*s()', 'second argument to likelihood must be a constant between 0.0 and 1.0', 'factory must return a cursor, not \\\\w+']