我正在Google Cloud Platform上使用BigQuery从GDELT中提取数据。这使用了SQL语法和正则表达式。
我有一列数据(称为V2Tone),其中每个单元格如下所示:
1.55763239875389,2.80373831775701,1.24610591900312,4.04984423676012,26.4797507788162,2.49221183800623,299
要使用正则表达式仅选择第一个数字(即,第一个逗号之前的数字),我们使用以下方法:
regexp_replace(V2Tone, r',.*', '')
我们如何仅选择第二个数字(即,第一个和第二个逗号之间的数字)?
第三个数字(即第二个和第三个逗号之间的数字)如何??
我知道这里使用了re2语法(https://github.com/google/re2/wiki/Syntax),但是我对如何将所有内容组合在一起的理解有限。
如果不清楚,请通知我。感谢您在我学习使用正则表达式时的帮助。
答案 0 :(得分:3)
下面的示例适用于使用超级简单的SPLIT方法的BigQuery Standard SQL
#standardSQL
SELECT
SPLIT(V2Tone)[SAFE_OFFSET(0)] first_number,
SPLIT(V2Tone)[SAFE_OFFSET(1)] second_number,
SPLIT(V2Tone)[SAFE_OFFSET(2)] third_number
FROM `project.dataset.table`
如果出于某种原因您需要/想要在此处使用regexp-在下面使用
#standardSQL
SELECT
REGEXP_EXTRACT(V2Tone, r'^(.*?),') first_number,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),)(.*?),') second_number,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),){2}(.*?),') third_number,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),){4}(.*?),') fifth_number
FROM `project.dataset.table`
请注意使用REGEXP_EXTRACT代替REGEXP_REPLACE
您可以使用以下问题中的虚拟字符串播放,测试以上选项
#standardSQL
WITH `project.dataset.table` AS (
SELECT '1.55763239875389,2.80373831775701,1.24610591900312,4.04984423676012,26.4797507788162,2.49221183800623,299' V2Tone
)
SELECT
SPLIT(V2Tone)[SAFE_OFFSET(0)] first_number,
SPLIT(V2Tone)[SAFE_OFFSET(1)] second_number,
SPLIT(V2Tone)[SAFE_OFFSET(2)] third_number,
REGEXP_EXTRACT(V2Tone, r'^(.*?),') first_number_re,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),)(.*?),') second_number_re,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),){2}(.*?),') third_number_re,
REGEXP_EXTRACT(V2Tone, r'^(?:(?:.*?),){4}(.*?),') fifth_number_re
FROM `project.dataset.table`
输出:
first_number second_number third_number first_number_re second_number_re third_number_re fifth_number_re
1.55763239875389 2.80373831775701 1.24610591900312 1.55763239875389 2.80373831775701 1.24610591900312 26.4797507788162
答案 1 :(得分:2)
我不知道可以使用一个正则表达式替换来隔离CSV字符串中的单个数字,因为一般来说,我们需要删除比赛双方的内容。但是,我们可以将两个对regex_replace
的调用链接在一起。例如,如果您要定位CSV字符串中的第三数字,我们可以尝试以下操作:
regexp_replace(regexp_replace(V2Tone, r'^(?:(?:\d+(?:\.\d+)?),){2}', ''),
r',.*', ''))
我用来剥离前n
个数字的模式是这样的:
^(?:(?:\d+(?:\.\d+)?),){n}
这只是从字符串的开头删除一个数字,然后删除n
次逗号。
答案 2 :(得分:2)
这是一个使用单个正则表达式替换的解决方案:
^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$
\n
已添加到演示中的否定字符类中,以避免在m | multiline模式下匹配跨行。
regexp_replace(V2Tone, r'^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$', '$1')
([^,]+(?:,|$){n}
将所有内容捕获到下一个逗号或字符串结尾n
次([^,]+(?:,|$))*
捕获其余0次或更多次^.*$
次,n
会捕获一切最后,我们可以使用n
重新插入第$1
个匹配项。