使用正则表达式从 Google BigQuery 中的字符串中提取数字
Extract numbers from string in Google BigQuery using regex
我想知道是否可以在 BigQuery 中使用正则表达式从字符串中提取所有数字。
我认为下面的方法有效,但只有 returns 第一次命中 - 有没有办法提取所有命中。
我在这里的用例是我基本上想从 url 中获得最大的数字,因为它更像是我需要加入的 post_id。
这是我所说的一个例子:
SELECT
mystr,
REGEXP_EXTRACT(mystr, r'(\d+)') AS nums
FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
我从中得到的结果是:
[
{
"mystr": "this is a string with some 666 numbers 999 in it 333",
"nums": "666"
},
{
"mystr": "just one number 123 in this one ",
"nums": "123"
},
{
"mystr": "99",
"nums": "99"
},
{
"mystr": "another -2 example 99",
"nums": "2"
},
{
"mystr": "another-8766 example 99",
"nums": "8766"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999",
"nums": "2015"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001",
"nums": "2015"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview",
"nums": "2015"
}
]
经过一番挖掘,我最终得到了这个解决方案:
SELECT
mystr,
GROUP_CONCAT(SPLIT(REGEXP_REPLACE(mystr, r'[^\d]+', ','))) AS nums
FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
工作原理:
- 我首先使用正则表达式匹配任何非数字并用逗号替换
- 然后用
split
得到结果,空结果被丢弃
group_concat
只是为了展示结果
虽然您将越来越多地在 BigQuery 中使用 Regex,但您会发现它的实现目前非常有限
BigQuery Regular expression functions
re2 Syntax
因此很可能很快您将不得不执行以下操作
请注意 - 对于您当前的具体示例 - 下面的代码与@Cybril
提供的简单解决方案相比绝对没有任何好处
此方案更能满足您近期的潜在需求
它使用 javascript UDF 从而为您提供 javascript 正则表达式实现的能力
BigQuery User-Defined Functions
SELECT mystr, MAX(number) as max_number FROM JS(
// input table
(SELECT mystr FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
) ,
// input columns
mystr,
// output schema
"[
{name: 'mystr', type: 'string'},
{name: 'number', type: 'string'}
]",
// function
"function(r, emit){
var numbers = r.mystr.match(/(\d+)/g);
for (var i=0; i < numbers.length; i++) {
emit({
mystr: r.mystr,
number: numbers[i]
});
};
}"
)
GROUP BY 1
当然你也可以把判断最大值的逻辑移到UDF里面,去掉多余的分组
我想知道是否可以在 BigQuery 中使用正则表达式从字符串中提取所有数字。
我认为下面的方法有效,但只有 returns 第一次命中 - 有没有办法提取所有命中。
我在这里的用例是我基本上想从 url 中获得最大的数字,因为它更像是我需要加入的 post_id。
这是我所说的一个例子:
SELECT
mystr,
REGEXP_EXTRACT(mystr, r'(\d+)') AS nums
FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
我从中得到的结果是:
[
{
"mystr": "this is a string with some 666 numbers 999 in it 333",
"nums": "666"
},
{
"mystr": "just one number 123 in this one ",
"nums": "123"
},
{
"mystr": "99",
"nums": "99"
},
{
"mystr": "another -2 example 99",
"nums": "2"
},
{
"mystr": "another-8766 example 99",
"nums": "8766"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999",
"nums": "2015"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001",
"nums": "2015"
},
{
"mystr": "http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview",
"nums": "2015"
}
]
经过一番挖掘,我最终得到了这个解决方案:
SELECT
mystr,
GROUP_CONCAT(SPLIT(REGEXP_REPLACE(mystr, r'[^\d]+', ','))) AS nums
FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
工作原理:
- 我首先使用正则表达式匹配任何非数字并用逗号替换
- 然后用
split
得到结果,空结果被丢弃 group_concat
只是为了展示结果
虽然您将越来越多地在 BigQuery 中使用 Regex,但您会发现它的实现目前非常有限
BigQuery Regular expression functions
re2 Syntax
因此很可能很快您将不得不执行以下操作
请注意 - 对于您当前的具体示例 - 下面的代码与@Cybril
提供的简单解决方案相比绝对没有任何好处
此方案更能满足您近期的潜在需求
它使用 javascript UDF 从而为您提供 javascript 正则表达式实现的能力
BigQuery User-Defined Functions
SELECT mystr, MAX(number) as max_number FROM JS(
// input table
(SELECT mystr FROM
(SELECT 'this is a string with some 666 numbers 999 in it 333' AS mystr),
(SELECT 'just one number 123 in this one ' AS mystr),
(SELECT '99' AS mystr),
(SELECT 'another -2 example 99' AS mystr),
(SELECT 'another-8766 example 99' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/gallery/001' AS mystr),
(SELECT 'http://somedomain.com/2015/12/this-is-a-post-with-id-in-url-99999/print-preview' AS mystr)
) ,
// input columns
mystr,
// output schema
"[
{name: 'mystr', type: 'string'},
{name: 'number', type: 'string'}
]",
// function
"function(r, emit){
var numbers = r.mystr.match(/(\d+)/g);
for (var i=0; i < numbers.length; i++) {
emit({
mystr: r.mystr,
number: numbers[i]
});
};
}"
)
GROUP BY 1
当然你也可以把判断最大值的逻辑移到UDF里面,去掉多余的分组