将字符串与特定文本匹配的正则表达式不在 BigQuery 中的文本之间
Regex that matches strings with specific text not between text in BigQuery
我有以下字符串:
step_1->step_2->step_3
step_1->step_3
step_1->step_2->step_1->step_3
step_1->step_2->step_1->step_2->step_3
我想做的是捕获 step_1 和步骤 3 之间没有 step_2 的那些。
结果应该是这样的:
string result
step_1->step_2->step_3 false
step_1->step_3 true
step_1->step_2->step_1->step_3 true
step_1->step_2->step_1->step_2->step_3 false
我曾尝试使用负前瞻,但我发现 BigQuery 不支持它。有什么想法吗?
你本质上是在寻找模式何时不存在。以下正则表达式将支持嵌入在 case 语句中的内容。这不支持您在单个字符串中同时具有两个条件的情况,但是您在示例数据中列出的情况并非如此。
尝试以下操作:
with sample_data as (
select 'step_1->step_2->step_3' as string union all
select 'step_1->step_3' union all
select 'step_1->step_2->step_1->step_3' union all
select 'step_1->step_2->step_1->step_2->step_3' union all
select 'step_1->step_2->step_1->step_2->step_2->step_3' union all
select 'step_1->step_2->step_1->step_2->step_2'
)
select
string,
-- CASE WHEN regexp_extract(string, r'step_1->(\w+)->step_3') IS NULL THEN TRUE
CASE WHEN regexp_extract(string, r'1(->step_2)+->step_3') IS NULL THEN TRUE
ELSE FALSE END as result
from sample_data
这导致:
我相信@Daniel_Zagales 的回答正是您所期待的。然而,这里有一个更广泛的解决方案,可能对您的 usecase:it 感兴趣,包括使用数组
WITH sample AS (
SELECT 'step_1->step_2->step_3' AS path
UNION ALL SELECT 'step_1->step_3'
UNION ALL SELECT 'step_1->step_2->step_1->step_3'
UNION ALL SELECT 'step_1->step_2->step_1->step_2->step_3'
),
temp AS (
SELECT
path,
SPLIT(REGEXP_REPLACE(path,'step_', ''), '->') AS sequences
FROM
sample)
SELECT
path,
position,
flattened AS current_step,
LAG(flattened) OVER (PARTITION BY path ORDER BY OFFSET ) AS previous_step,
LEAD(flattened) OVER (PARTITION BY path ORDER BY OFFSET ) AS following_step
FROM
temp,
temp.sequences AS flattened
WITH
OFFSET AS position
本次查询returns以下table
概念是获取步数数组(拆分“->”并擦除 'step_')并保留 OFFSET
(作为 UNNEST
ing 数组至关重要不保证保持数组的顺序)。
得到的table包含了该路径的每条路径和步骤,前一步和后一步。因此,如果连续的步骤相差 1,则很容易测试。
(例如SELECT * FROM <previous> WHERE ABS(current_step-previous_step) != 1
)
(需要 CAST
到 INT
)
同时考虑以下选项
select string,
not regexp_contains(string, r'step_1->(step_2->)+step_3\b') as result
from your_table
我有以下字符串:
step_1->step_2->step_3
step_1->step_3
step_1->step_2->step_1->step_3
step_1->step_2->step_1->step_2->step_3
我想做的是捕获 step_1 和步骤 3 之间没有 step_2 的那些。
结果应该是这样的:
string result
step_1->step_2->step_3 false
step_1->step_3 true
step_1->step_2->step_1->step_3 true
step_1->step_2->step_1->step_2->step_3 false
我曾尝试使用负前瞻,但我发现 BigQuery 不支持它。有什么想法吗?
你本质上是在寻找模式何时不存在。以下正则表达式将支持嵌入在 case 语句中的内容。这不支持您在单个字符串中同时具有两个条件的情况,但是您在示例数据中列出的情况并非如此。
尝试以下操作:
with sample_data as (
select 'step_1->step_2->step_3' as string union all
select 'step_1->step_3' union all
select 'step_1->step_2->step_1->step_3' union all
select 'step_1->step_2->step_1->step_2->step_3' union all
select 'step_1->step_2->step_1->step_2->step_2->step_3' union all
select 'step_1->step_2->step_1->step_2->step_2'
)
select
string,
-- CASE WHEN regexp_extract(string, r'step_1->(\w+)->step_3') IS NULL THEN TRUE
CASE WHEN regexp_extract(string, r'1(->step_2)+->step_3') IS NULL THEN TRUE
ELSE FALSE END as result
from sample_data
这导致:
我相信@Daniel_Zagales 的回答正是您所期待的。然而,这里有一个更广泛的解决方案,可能对您的 usecase:it 感兴趣,包括使用数组
WITH sample AS (
SELECT 'step_1->step_2->step_3' AS path
UNION ALL SELECT 'step_1->step_3'
UNION ALL SELECT 'step_1->step_2->step_1->step_3'
UNION ALL SELECT 'step_1->step_2->step_1->step_2->step_3'
),
temp AS (
SELECT
path,
SPLIT(REGEXP_REPLACE(path,'step_', ''), '->') AS sequences
FROM
sample)
SELECT
path,
position,
flattened AS current_step,
LAG(flattened) OVER (PARTITION BY path ORDER BY OFFSET ) AS previous_step,
LEAD(flattened) OVER (PARTITION BY path ORDER BY OFFSET ) AS following_step
FROM
temp,
temp.sequences AS flattened
WITH
OFFSET AS position
本次查询returns以下table
概念是获取步数数组(拆分“->”并擦除 'step_')并保留 OFFSET
(作为 UNNEST
ing 数组至关重要不保证保持数组的顺序)。
得到的table包含了该路径的每条路径和步骤,前一步和后一步。因此,如果连续的步骤相差 1,则很容易测试。
(例如SELECT * FROM <previous> WHERE ABS(current_step-previous_step) != 1
)
(需要 CAST
到 INT
)
同时考虑以下选项
select string,
not regexp_contains(string, r'step_1->(step_2->)+step_3\b') as result
from your_table