read_gbq 函数中 REGEXP_EXTRACT 中的正则表达式失败

Posted

技术标签:

【中文标题】read_gbq 函数中 REGEXP_EXTRACT 中的正则表达式失败【英文标题】:Regular Expression failing in REGEXP_EXTRACT within the read_gbq function 【发布时间】:2019-09-26 17:49:18 【问题描述】:

我未能在 read_gbq 函数中成功执行正则表达式函数(即 REGEXP_EXTRACT)。

read_gbq 来自 pandas_gbq 模块。

我的 Python 程序中的 import 语句是:from pandas_gbq import read_gbq。

我的环境中pandas-gbq的版本是:0.8.0

我认为,正则表达式失败是因为无法识别双引号上的黑色斜线转义字符。

这个正则表达式在 Big Query 和使用 Python 的在线 RegEx 测试器中运行良好(参见下面的代码部分)。

感谢您的时间和关注

component = 'CO_ORDER_SUMMARY'
def Read_CO_Order_Summary():                            

        query = ('select co.timestamp, co.jsonPayload._userid_ as co_SVOC, co.jsonPayload.response,  \
                 REGEXP_EXTRACT(co.jsonPayload.response, customerOrderId\":\"([^\"]*)\".*) as CustomerOrderID \
        from `exported_logs_v2.mcc_checkout_service_servicelog_20190623` co  '
             'where co.jsonPayload.component = ' '"' + component + '"' 

      'order by co.timestamp, co.jsonPayload._userid_ '
      'limit 1'
                  )

        co_agg = read_gbq(query, projectid, dialect='standard')

        return(co_agg)
co_agg = Read_CO_Order_Summary()

**ERROR MESSAGE**
GenericGBQException: Reason: 400 Syntax error: Expected “)” but got string literal “:” at [1:253]
****************************************
IN REGEX101.com TESTER (using the Python "flavor" setting)
REGEX
customerOrderId\":\"([^\"]*)\".*
STRING
"lastModifiedDate":"2019-06-23 16:50:18.212","localStoreId":1515,"cartId":"HC100006597310","customerOrderId":"W838207358","
RESULT
Match 1     
Full match  customerOrderId":"W838207358"," 
Group 1.    W838207358
******************* Big Query ******************
SELECT timestamp, jsonpayload._userid_, jsonpayload.response, 
 -- REGEXP_EXTRACT(jsonPayload.response, r'\"customerOrderId\":\"(.*?)\","')  as CustomerOrderID,    ## All 3 of these work 
 -- REGEXP_EXTRACT(jsonPayload.response, r"customerOrderId\":\"(.*?)\",")     as CustomerOrderID  
    REGEXP_EXTRACT(jsonPayload.response, r"customerOrderId\":\"([^\"]*)\".*") as CustomerOrderID  
FROM `exported_logs_v2.mcc_checkout_service_servicelog_201906*`
   where jsonpayload.component like '%CO_ORDER_SUMMARY%'   ##'%CO_ORDER_SUMMARY%'  or   '%CO_SECURE_LOGON%'
     and ( _TABLE_SUFFIX between "23" and "23" )
     and   jsonPayload._userid_ = "0516CFC3D4B001FB0S" 
 order by timestamp asc

【问题讨论】:

您的查询字符串是有效字符串吗?您看起来有几个 ' 引号而没有将任何东西连接在一起。您能否将您的函数修改为 print(query) 并确保它给出了您期望的语句? 感谢您的建议 rtenha。单引号是创建查询字符串所必需的,不平衡的单引号将被解析器捕获并指示“扫描字符串文字时 EOL”警告。我的引用中没有这样的警告。 知道了。我不熟悉python中的字符串连接方法。注意,如果co.jsonPayload.response是一个有效的JSON字符串,你也可以使用JSON_EXTRACT_SCALAR(co.jsonPayload.response, '$.customerOrderId') 成功了!非常感谢。我仍然想了解为什么 REGEXP_EXTRACT 函数在 Big Query 和正则表达式测试器中有效,但在 read_gbq 函数中无效。请将此作为答案提交,以便我为您提供信用。再次感谢! 【参考方案1】:

如果 co.jsonPayload.response 是有效的 JSON 字符串,则可以使用 JSON_EXTRACT_SCALAR(co.jsonPayload.response, '$.customerOrderId')

【讨论】:

【参考方案2】:

您应该在 python 字符串中转义 \ 字符 - 只需将 \ 替换为 \\

【讨论】:

感谢您的建议。我已经尝试过“逃避逃脱”,但这并没有解决问题。同样,此 RegEx 在 Big Query 和在线 RegEx 测试器中都能成功运行。我相信应该足够的单个转义字符没有被识别为转义字符。 其实你可以尝试将你的SQL查询保存到文件中,然后在python中打开并执行它。这样它将保留任何奇怪的字符。 不确定我是否关注。您看到的代码是从 .py 程序中截取的,所以我不确定将它保存到另一个文件然后重新打开它会完成什么。 我的意思是将原始查询字符串保存为单独的文件。如果你用 open() 函数阅读它,你不会因为逃避怪异而丢失任何字符。

以上是关于read_gbq 函数中 REGEXP_EXTRACT 中的正则表达式失败的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 pandas.read_gbq() 函数时,pandas-gbq 抛出错误“找不到字段 google.protobuf.FileOptions.php_metadata_namespace”

在 Jupyter Notebook 中进行时,pandas.read_gbq() 在哪里“保存”查询?

如何防止 pandas.read_gbq 推断列的数据类型

如何避免 pd.read_gbq 访问错误的电子邮件以访问大查询

pandas read_gbq 不工作并显示错误

如何在使用 Pandas.read_gbq 加载带有列表列的表后恢复结构?