删除元素的正则表达式与特定前缀不匹配
Posted
技术标签:
【中文标题】删除元素的正则表达式与特定前缀不匹配【英文标题】:Regular expression to remove element not match specific prefix 【发布时间】:2018-06-27 22:59:29 【问题描述】:我在 Impala 或 Hive 中执行此操作。基本上假设我有一个这样的字符串
f-150:aa|f-150:cc|g-210:dd
每个元素由管道|
分隔。每个都有前缀f-150
或其他。我希望能够删除前缀并仅保留与特定前缀匹配的元素。比如前缀是f-150
,我希望regex_replace后面的最后一个字符串是
aa|cc
dd
被移除,因为g-210
是不同的前缀并且不匹配,因此整个元素被移除。
知道如何在一个 SQL 中使用字符串表达式来做到这一点吗?
谢谢
更新 1
我在Impala
中试过这个:
select regexp_extract('f-150:aa|f-150:cc|g-210:dd','(?:(?:|(\\|))f-150|keep|those):|(?:^|\\|)\\w-\\d3:\\w2',0);
但是得到了这个输出:
f-150:aa
在Hive
,我得到了NULL
。
【问题讨论】:
【参考方案1】:有问题的正则表达式可能如下所示:
(?:(?:|(\\|))f-150|keep|those):|(?:^|\\|)\\w-\\d3:\\w2
我添加了一些伪关键字来保留,但我相信你明白了:
完全匹配应删除的元素,但仅匹配应保留的前缀。 要保持分隔符不变,请将|
匹配到组 1 中元素的开头,然后用$1
将其放回替换位置。
Demo
根据documentation,您的查询应该写成Java regex;同样,这应该像这样code sample in Java。
【讨论】:
感谢您的帮助。我在网上其他地方尝试了正则表达式,它可以工作,但由于某种原因在 Impala 和 Hive 中,它没有。请看我上面的更新。【参考方案2】:您可以匹配要删除的值,然后用空字符串替换:
f-150:|\|[^:]+:[^|]+$|[^|]+:[^|]+\|
f-150:|\\|[^:]+:[^|]+$|[^|]+:[^|]+\\|
解释
f-150:
字面匹配
|
或者
\|[^:]+:[^|]+$
匹配一个管道,而不是冒号一次或多次,后跟非管道一次或多次并断言行尾
|
或者
[^|]+:[^|]+\|
不匹配管道一次或多次,冒号后跟非管道匹配一次或多次,然后匹配管道
Test with multiple lines and combinations
【讨论】:
由于某种原因,Impala 在执行select regexp_extract('f-150:aa|f-150:cc|g-210:dd','f-150:|\\|[^:]+:[^|]+$|[^|]+:[^|]+\\|',0);
时一直只提供f-150:aa|
如果你使用 regexp_replace,也许像regexp_replace("f-150:aa|f-150:cc|g-210:dd", "f-150:|\\|[^:]+:[^|]+$|[^|]+:[^|]+\\|", "")
我跑了select regexp_replace('f-150:aa|f-150:cc|g-210:dd','f-150:|\\|[^:]+:[^|]+$|[^|]+:[^|]+\\|','NA');
,得到了NANAg-210:dd
,所以看起来它做对了。
我想如果有可能作为解决方法,我可以用空字符替换“none f-150”。基本上g-210:dd
会被清空。【参考方案3】:
您可能必须遍历字符串直到结束才能获得所有匹配的子字符串。大多数 sql 不支持前瞻语法,因此上述正则表达式可能不适合 SQL 语法。出于您的目的,您可以执行一些操作,例如创建一个循环遍历的表,以模仿 Oracle 的级别语法并与包含字符串的表连接。
With loop_tab as (
Select 1 loop union all
Select 2 union all
select 3 union all
select 4 union all
select 5),
string_tab as(Select 'f-150:aa|ade|f-150:ce|akg|f-150:bb|'::varchar(40) as str)
Select regexp_substr(str,'(f\\-150\\:\\w+\\|)',1,loop)
from string_tab
join loop_tab on 1=1
输出:
regexp_substr
f-150:aa|
f-150:ce|
f-150:bb|
【讨论】:
以上是关于删除元素的正则表达式与特定前缀不匹配的主要内容,如果未能解决你的问题,请参考以下文章