regex 在BigQuery中提取子字符串

zdwk9cvp  于 2023-01-06  发布在  其他
关注(0)|答案(2)|浏览(176)

| 身体|
| - ------|
| /tpt/Tp扫描-扫描道路-持久性-202301020730327429 - 1567651.tp|
| /tpt/Tp扫描-巴厘岛度假村实习生-PERSIVEE-202205300341154744 - 909890.tp|
| /tpt/tp扫描-RXX-持久性-202108210412090110 - 000989.tp|
| /tpt/tp扫描-背景说明-持久性-202112201229124214 - 783672.tp|
| /tpt/tp扫描-数据库-持久性-202109131129036172 - 908954.tp|
| /tpt/tp扫描-数据库-持久性-202109131129036172 - 17892578.tp|
我在BigQuery表xyz中有一个列"正文",其中包含我们内部应用程序上请求的扫描。正文字段包含日期部分,即(202301020730327429、202205300341154744 ...)18位数字。
我希望在名为date的单独列中提取此18位数序列,以了解扫描请求是何时创建的。
我试着使用substr函数,但是它不能正常工作,因为Body字段的长度是变化的。有没有更好的方法来实现它?
预期产出:
| 日期|
| - ------|
| 小行星2023|
| 二○二二○五三○ ○三四一一五四七四四|
| 小行星2021|
| 小行星20211年2月20日|
| 小行星202109|
| 小行星202109|

rwqw0loc

rwqw0loc1#

你可以考虑下面。

WITH sample_table AS (
  SELECT '/tpt/TpScaning-ScaningRoad-PERSIVEE-202301020730327429-1567651.tp' body UNION ALL
  SELECT '/tpt/TpScaning-BaliResortsInterns-PERSIVEE-202205300341154744-909890.tp' body UNION ALL
  SELECT '/tpt/TpScaning-RXX-PERSIVEE-202108210412090110-000989.tp' body UNION ALL
  SELECT '/tpt/TpScaning-Backnationnotecom-PERSIVEE-202112201229124214-783672.tp' body UNION ALL
  SELECT '/tpt/TpScaning-DBZ-PERSIVEE-202109131129036172-908954.tp' body UNION ALL
  SELECT '/tpt/TpScaning-DBZ-PERSIVEE-202109131129036172-17892578.tp' body
)
SELECT *, PARSE_TIMESTAMP('%Y%m%d%H%M%E4S', LEFT(date, 14) || '.' || RIGHT(date, 4)) ts 
  FROM (
    SELECT *, REGEXP_EXTRACT(body, r'\d{18}') AS date FROM sample_table
  );
一些解释
  • 正则表达式解释-〉https://regex101.com/r/fiB4mD/1
  • \d匹配1个数字(相当于[0 - 9])
  • {18}与前一个令牌正好匹配18次
  • REGEXP_EXTRACT函数将从给定的字符串数据中查找上面正则表达式中描述的模式。
  • %E4S元素parse * seconds,带有小数精度的数字 *,即00.0000 for %E4S。请注意,它需要在字符串数据中使用点(.)。
    • 查询结果**

6tdlim6h

6tdlim6h2#

也考虑以下方法

select body, regexp_extract(body, r'\d{18}') as date,
  timestamp(regexp_replace(body, r'(^.*?)(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{4})(.*?$)', r'\2-\3-\4 \5:\6:\7.\8')) as ts
from your_table

如果应用于问题中的样本数据-输出为

相关问题