Python 使用正则表达式从c源获取函数调用的第二个字符串参数

Python 使用正则表达式从c源获取函数调用的第二个字符串参数,python,python-3.x,regex,Python,Python 3.x,Regex,我正在尝试解析SQLite源代码中的错误消息,我认为我目前的方法涵盖了大多数情况 我的正则表达式: (?:sqlite3ErrorMsg|sqlite3MPrintf|sqlite3VdbeError)\([^;\"]+\"([^)]+)\"(?:,|\)|:) 源代码段(无效的C,仅用于演示): 但是,由于(),它错过了函数%.*s()的错误数量的参数 我还尝试过从“捕获到”,并对其进行反向查看,以允许转义的\“(不要跳过no\”这样的“函数:%.*s),但我

我正在尝试解析SQLite源代码中的错误消息,我认为我目前的方法涵盖了大多数情况

我的正则表达式:

(?: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+']