如何使用正则表达式来 select 逗号之间的文本?
How can I use regular expressions to select text between commas?
我在 Google Cloud Platform 上使用 BigQuery 从 GDELT 中提取数据。这使用 SQL 语法和正则表达式。
我有一列数据(称为 V2Tone),其中每个单元格如下所示:
1.55763239875389,2.80373831775701,1.24610591900312,4.04984423676012,26.4797507788162,2.49221183800623,299
到select只有第一个数字(即第一个逗号前的数字)使用正则表达式,我们使用这个:
regexp_replace(V2Tone, r',.*', '')
如何才能select只有第二个数字(即第一个和第二个逗号之间的数字)?
第三个数字如何(即第二个和第三个逗号之间的数字)?
我知道这里使用了 re2 语法 (https://github.com/google/re2/wiki/Syntax),但我对如何将它们组合在一起的理解有限。
如有不明之处,请告诉我。感谢您帮助我学习使用正则表达式。
我不知道可以使用单个正则表达式替换来隔离 CSV 字符串中的单个数字,因为通常我们需要删除匹配两边的内容。但是,我们可以将对 regex_replace
的两个调用链接在一起。例如,如果您想定位 CSV 字符串中的 third 数字,我们可以尝试这样做:
regexp_replace(regexp_replace(V2Tone, r'^(?:(?:\d+(?:\.\d+)?),){2}', ''),
r',.*', ''))
我用来去除前 n
个数字的模式是这样的:
^(?:(?:\d+(?:\.\d+)?),){n}
这只是从字符串的开头删除一个数字,后跟一个逗号 n
次。
这是一个使用单个正则表达式替换的解决方案:
^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$
Demo
\n
在demo中的取反符class后面添加,避免m|多行模式下跨行匹配
用法:
regexp_replace(V2Tone, r'^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$', '')
解释:
([^,]+(?:,|$){n}
捕获下一个逗号或字符串末尾的所有内容 n
次
([^,]+(?:,|$))*
捕获其余 0 次或更多次
^.*$
如果我们无法匹配 n
次 ,则捕获所有内容
最后,我们可以使用 </code>.</p> 重新插入第 <code>n
个匹配项
以下示例适用于 BigQuery Standard SQL 使用超级简单的 SPLIT 方法
#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`
如果出于某种原因您 need/want 在这里使用正则表达式 - 请在下面使用
#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
我在 Google Cloud Platform 上使用 BigQuery 从 GDELT 中提取数据。这使用 SQL 语法和正则表达式。
我有一列数据(称为 V2Tone),其中每个单元格如下所示:
1.55763239875389,2.80373831775701,1.24610591900312,4.04984423676012,26.4797507788162,2.49221183800623,299
到select只有第一个数字(即第一个逗号前的数字)使用正则表达式,我们使用这个:
regexp_replace(V2Tone, r',.*', '')
如何才能select只有第二个数字(即第一个和第二个逗号之间的数字)?
第三个数字如何(即第二个和第三个逗号之间的数字)?
我知道这里使用了 re2 语法 (https://github.com/google/re2/wiki/Syntax),但我对如何将它们组合在一起的理解有限。
如有不明之处,请告诉我。感谢您帮助我学习使用正则表达式。
我不知道可以使用单个正则表达式替换来隔离 CSV 字符串中的单个数字,因为通常我们需要删除匹配两边的内容。但是,我们可以将对 regex_replace
的两个调用链接在一起。例如,如果您想定位 CSV 字符串中的 third 数字,我们可以尝试这样做:
regexp_replace(regexp_replace(V2Tone, r'^(?:(?:\d+(?:\.\d+)?),){2}', ''),
r',.*', ''))
我用来去除前 n
个数字的模式是这样的:
^(?:(?:\d+(?:\.\d+)?),){n}
这只是从字符串的开头删除一个数字,后跟一个逗号 n
次。
这是一个使用单个正则表达式替换的解决方案:
^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$
Demo
\n
在demo中的取反符class后面添加,避免m|多行模式下跨行匹配
用法:
regexp_replace(V2Tone, r'^([^,]+(?:,|$)){2}([^,]+(?:,|$))*|^.*$', '')
解释:
([^,]+(?:,|$){n}
捕获下一个逗号或字符串末尾的所有内容n
次([^,]+(?:,|$))*
捕获其余 0 次或更多次^.*$
如果我们无法匹配n
次 ,则捕获所有内容
最后,我们可以使用 </code>.</p> 重新插入第 <code>n
个匹配项
以下示例适用于 BigQuery Standard SQL 使用超级简单的 SPLIT 方法
#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`
如果出于某种原因您 need/want 在这里使用正则表达式 - 请在下面使用
#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