我有一个 json 数组,需要从中提取字符串。我们将这些数据存储在 Bigquery 中,除了从数组的 user_id 字段中提取 id 之外,大部分数据都非常简单。关于
user_id
如何出现有七个可能的字符串。例如,在 json 数组中,user_id
可能是这样的: "user_id": "client-id-12345678-abcd-0926-zyxw-de07e3f9ce85"
或者它可能是 "user_id": "operator-id-12345678-abcd-0926-zyxw-de07e3f9ce85"
或 "user_id": "auto_agent_id_12345678-abcd-0926-zyxw-de07e3f9ce85"
示例 json 如下所示:
{
"members": [
{
"channel_count": 0,
"profile_url": "something.png",
"push_enabled": true,
"push_trigger_option": "default",
"state": "joined",
"user_id": "desk_agent_id_12345678-abcd-0926-zyxw-de07e3f9ce85"
}
]
}
我认为最初处理这个问题的最佳方法是运行 sql 替换,如下所示:
replace(replace('client-us-operator-us-iddddddd','client-us-', '' ), 'operator-us-', '')
但是因为有几个不同的 user_id 前缀,这使得它变得很困难。我不确定这些是否是所有可能的边缘情况。如果只是客户端和操作员,那就 12345678-abcd-0926-zyxw-de07e3f9ce85
并且可以按预期工作。当它是 "desk_agent_id_12345678-abcd-0926-zyxw-de07e3f9ce85"
时,它会拉动整根弦,有时 user_id
显示为 "agent_id_12345678-abcd-0926-zyxw-de07e3f9ce85"
我只需要前缀右侧的所有内容。所以在这种情况下它会是
12345678-abcd-0926-zyxw-de07e3f9ce85
。但是,取决于它是自动消息还是用户响应前缀长度以及连字符或下划线的变化。
我在使用正则表达式方面并不是最强的,所以我来这里是为了看看是否有更好的方法来处理从整个 user_id 字符串中提取此 id。
REGEXP
是您想要使用的,因为它允许定义一组用于包含和排除的模式匹配。答案在底部
功能详细说明:
JSON_EXTRACT_SCALAR(json_string, json_path)
$.fieldname
指向 JSON 对象的根($),以及要定位的特定字段(.fieldname)。JSON_EXTRACT(your_json_object, '$.user_id')
-从我的json中,找到user_id的根键值对。
REGEXP_EXTRACT(string, regex_pattern)
:
对于字符串,匹配模式。
JSON_EXTRACT()
r'^(?:client-id-|operator-id-|auto_agent_id_|desk_agent_id_)([a-zA-Z0-9-]+)$'
^
指向字符串的开头(?:client-id-|operator-id-|auto_agent_id_|desk_agent_id_)
非捕获组。 (?...)
语法对前缀进行分组,而不在输出中捕获它们。您可以在此处放置不同的前缀可能性。([a-zA-Z0-9-]+)
这是您想要在输出中出现的捕获组。从左到右,它表示:捕获 a-z(小写)、A-Z(大写)、0-9(数字)、-(连字符)之间的任何内容。如果您希望 ids 具有其他捕获的格式,则可以将其包含在此处。例如句号或斜线。$
表示字符串的结尾。WITH sample_data AS (
SELECT '''
{
"members": [
{
"channel_count": 0,
"profile_url": "something.png",
"push_enabled": true,
"push_trigger_option": "default",
"state": "joined",
"user_id": "desk_agent_id_12345678-abcd-0926-zyxw-de07e3f9ce85"
},
{
"channel_count": 1,
"profile_url": "another.png",
"push_enabled": false,
"push_trigger_option": "custom",
"state": "joined",
"user_id": "operator-id-87654321-zyxw-0926-abcd-ce85de07e3f9"
}
]
}
''' AS json_data
)
SELECT
REGEXP_EXTRACT(JSON_EXTRACT_SCALAR(m, '$.user_id'), r'^(?:client-id-|operator-id-|auto_agent_id_|desk_agent_id_)([a-zA-Z0-9-]+)$') AS extracted_user_id
FROM
sample_data,
UNNEST(JSON_EXTRACT_ARRAY(json_data, "$.members")) AS m