Redshift 中的 REGEXP_SUBSTR 函数不返回预期值
Posted
技术标签:
【中文标题】Redshift 中的 REGEXP_SUBSTR 函数不返回预期值【英文标题】:REGEXP_SUBSTR function in Redshift does not return expected value 【发布时间】:2019-11-20 07:34:58 【问题描述】:我有一个名为 URL 的列的表。我正在尝试使用 Redshift 中的REGEX_SUBSTR
函数提取 URL 的不同部分。
URL Expected_output
------------
www.abcd.com/first-name | first-name
www.abcd.com/another-name/some-details/other | another-name
www3.abcd.com/some-name/ | some-name
form.abcd.com/another-first-name | another-first-name
所以目的是提取域名后的第一个slug
我试过了SELECT REGEXP_SUBSTR('www.abcd.com/slug-name', '(www|www3|form)[.]abcd[.][^/]+/([^/#?]+)',1,2)
输出www.abcd.com/slug-name
【问题讨论】:
如果你使用REGEXP_SUBSTR('www.abcd.com/slug-name', '[^/]+',1,2)
会怎样?还是只需要在特定上下文中匹配?
请提供有关您希望匹配发生的确切上下文的反馈,这很重要,因为此正则表达式引擎似乎不支持非捕获组。你需要检查(www|www3|form)
吗?
是的,我需要检查这是一个以www|www3|form
开头的有效网址
那么我认为你不能使用REGEXP_SUBSTR
,因为它只能提取 first 捕获组的内容,其他的被忽略,因为它使用 POSIX 正则表达式标准,不支持非捕获组。您需要使用两步解决方案。
知道了。 2 步是指使用 UDF 吗?
【参考方案1】:
由于您需要在模式中进行多个分组,第一个分组定义了预期的匹配上下文(因此,您不需要提取第一组内容),并且REGEXP_SUBSTR
仅支持使用e
提取第一组修饰符,你必须回退到REGEXP_REPLACE
。
注意:REGEXP_REPLACE
删除匹配项,如果字符串没有匹配项,它将保持原样。 REGEXP_SUBSTR
将返回一个空白值。
所以,你可以考虑
REGEXP_REPLACE('www.abcd.com/slug-name', '^(www3?|form)\\.abcd\\.[^/]+/([^/#?]+).*', '$2')
或者,删除不匹配的条目文本(注意末尾添加的|.+
):
REGEXP_REPLACE('www.abcd.com/slug-name', '^(www3?|form)\\.abcd\\.[^/]+/([^/#?]+).*|.+', '$2')
所以,^(www3?|form)\\.abcd\\.[^/]+/([^/#?]+).*
匹配
^
- 字符串开头
(www3?|form)
- 第 1 组:www
和可选的 3
\.abcd\.
- .abcd.
子字符串
[^/]+
- 除/
之外的 1+ 个字符
/
- 一个 /
字符
([^/#?]+)
- 第 2 组(通过替换模式中的 $2
反向引用引用):除 /
、#
和 ?
之外的 1 个或多个字符
.*
- 尽可能多的任何 0+ 个字符
|.+
表示“或任何 1+ 个字符”。也就是说,如果第一个替代项没有找到匹配项,则删除整个文本。
【讨论】:
【参考方案2】:您可以忽略直到第一个正斜杠的任何内容,在第一个正斜杠之后捕获组,直到第二个(如果存在)。在捕获组中,您想要获取带有字符(可能不是大写)、连字符和下划线的任何内容。我发现 '\w-' 匹配下划线和连字符。
试试这个表达式:
^.*?\/([\w-]+)\/?.*
我在以下字符串上对此进行了测试:
www.abcd.com/first-name
www.abcd.com/another-name/some-details/other
www3.abcd.com/some-name/
form.abcd.com/another-first-name
form.abcd.com/another_first-name
form.abcd.com/anotherfirst-name
我使用tool on Regex 101 给我这些匹配项:
Match 1
Full match 0-44 www.abcd.com/first-name
Group 1. 13-23 first-name
Match 2
Full match 45-90 www.abcd.com/another-name/some-details/other
Group 1. 58-70 another-name
Match 3
Full match 91-135 www3.abcd.com/some-name/
Group 1. 105-114 some-name
Match 4
Full match 136-168 form.abcd.com/another-first-name
Group 1. 150-168 another-first-name
Match 5
Full match 169-201 form.abcd.com/another_first-name
Group 1. 183-201 another_first-name
Match 6
Full match 202-233 form.abcd.com/anotherfirst-name
Group 1. 216-233 anotherfirst-name
【讨论】:
Invalid preceding regular expression prior to repetition operator. The error occurred while parsing the regular expression fragment: '^.*?>>>HERE>>>/([w-]+)/?'
一些类似的错误***.com/questions/46495580/redshift-regexp-substr
啊,我担心正则表达式版本会有所不同。我不确定,也许尝试替换懒惰的“。*?”用'[\w.]+',恐怕我对Redshift不熟悉,也没有办法测试。
@JamesBaker 您的正则表达式不适用于 OP 代码。您需要包括使用示例。以上是关于Redshift 中的 REGEXP_SUBSTR 函数不返回预期值的主要内容,如果未能解决你的问题,请参考以下文章
Redshift REGEXP_SUBSTR 函数的 Spark 替代方案
HIVE SQL 中的 REGEXP_SUBSTR 等效项?