以下摘自:regexp正则表达式:提取目标内容
在hive环境中相关的函数有如下三个:
select
case when company regexp '.*公司$' then 1 when company regexp '.*中心$' then 2 end company_category
.
用来匹配除了换行符以外的任意单个字符 。
在正则表达式中,真正意义的通配符仅仅只有这一个,不像SQL中会区分%
(任意多个字符)和_
(单个字符)。不过正则表达式中还有更高级的统配符,可以用来匹配字符、空白以及数字等。
\d
匹配单个数字
\w
匹配单个字符 ,在ASCII码中等价于 [a-zA-Z0-9_] ,在Unicode中则更加匹配内容更加广泛
\s
匹配单个空白字符,包含space、tab以及换行符等
\b
匹配单词边界
[abc]
匹配范围内的单个字符串,这个例子可以匹配a、b或者c;这个例子也可以表示为[a-c]
^
匹配开头
$
匹配结尾 ,如果开始拥有权力,必然最后获得金钱。
上面都强调是单个字符,那么如何匹配多个字符呢?
在正则表达式中,有两种形式类匹配重复字符,一种通过特定的字符来控制,一种通过数字来说明。
?
重复0次或者1次 ;
*
重复0次以上 ; 重复0次,说明前面的字符可以不存在。
+
重复1次以上 。
那么如果希望更精确的控制候选字符串数量,就需要使用到其中一个控制数字的方式了,这就是{ }
,可以控制在特定的数值或者特定区间,指定上限或者下限。
{n}
重复n次;
{n,m}
重复n到m次
如果上限没有指定,也就是m置空,则表示字符串重复n次及以上。 注意上面的规则都是添加到前一个字符上的,如果是希望匹配重复的字符串,就是使用到( )
符号,其后跟随数值限定表达式,例如(test){1,3}
就可以匹配test
、testtest
以及testtesttest
字符串。
( )
还有一个重要的作用来表示捕获组(capture group),对于捕获组的内容有两种引用方式,一个是在正则表达式外部引用,另一个就是在内部引用,后者也常被称为反向引用。
反向引用是用来识别重复模式的,例如经常说到ABAB模式,就是AB的重复。包含反向参考的正则表达式有如下特征:(xxx)\number
,其中的number用来指代正则表达式中第几个捕获组,捕获组序号从1开始。
理论上太过于抽象, 通过例子看会更加清晰。 (\w+)\s+\1
这个表达式可以识别连续的重复单词,例如go go
等,利用的就是反向引用,利用\1
来表示表示(\w+)
所匹配到的内容,同样多个分组也是可以匹配上的,(\w+)\s+(\w+)\s+\1\s+\2
可以识别出go here go here
这样的模式。
上述已经构成了一个正则表达式的基本规则,但是在实际使用中会添加几个标识符来实现更便捷的功能。在不同的语言中不同的正则表达式模块实现的flags不同,但一般均包含以下方法
注意,有些模式下会导致有些API的使用行为会有所不同,例如g模式下,JavaScript中每次调用exec会依次返回匹配到内容,而在其他语言环境下可能就不存在这种模式,或者通过all这个参数来实现这样的功能。
set target="wake_up_running_app=ComponentInfo{com.xxx.xxx/xxx}";
SELECT regexp_extract(${hiveconf:a}, 'ComponentInfo\\{(.{1,50})/',1)
上面的脚本就是实现提取com.xxx.xxx
这个应用包名,下面的正则匹配样式也很简单,最关键也是自己出错了的地方就是如何实现{
的转义,因为{}
在正则表达式中用来表征数据范围,所以在表示原有的本来含义时就需要使用转义。但是恰巧在转移字符\
在正则表达式中也有其特殊含义,故需也进行一次转义。这样就得到了上面表达式的关键部分\\{
。
转移特殊字符是很不直观的,例如想匹配网址中的 //
部分,写成正则表达式则为////
,不过熟悉后就好。
select distinct phone, regexp_replace(get_json_object(contact,'$.c2'),' |\\+86|-','') phn_num