个人博客,记录知识防止遗忘
hive中函数regexp_extract 正则 截取字符串
hive中函数regexp_extract 正则 截取字符串

hive中函数regexp_extract 正则 截取字符串

最近有个需求,需要在hive数据仓库中筛选一批较为规整的数据, 并将其中特定字符截取出来,并统计分析。
过程中用到了正则匹配的函数 regexp_extract,现简单记录下,方便以后使用时查阅。

内容大纲

1    regexp_extract 函数语法

2.1    基础语法

语法: regexp_extract(string A, string pattern, int index)
返回值: string
说明:将字符串A按照正则表达式的规则拆分,返回index指定的部分(从1开始,0表示输出所有已匹配值)
简而言之,index为0时会返回所有匹配,index为其他值n时,只返回第n段匹配

举例:

regexp_extract('【e往无前】亚索您好,电刀正申请退货,验证码666666','[0-9]{6}',0)

此时返回值为 正则匹配到的 666666

regexp_extract('【e往无前】亚索您好,电刀正申请退货,验证码666666','(^【.*】).*[0-9]{6}',0)

此时返回值为 括号括起来的段匹配,即【e往无前】

2.2    正则贪婪模式的影响

regexp_extract('【e往无前】亚索您已掉线333天,封号666天','(^【.*】).*([0-9]{3})',2)

此时返回值为 第2个括号括起来的匹配,即([0-9]{3}) 匹配到的  666
额外说明: 返回值之所以不是前边的333 , 是因为在贪婪(默认)模式下,正则引擎会尽可能匹配更长的字符,若在.*后加上?则可关闭贪婪模式,开启懒惰模式。此时正则引擎会 尝试尽可能匹配更多次字符

regexp_extract('【e往无前】亚索您已掉线333天,封号666天','(^【.*】).*?([0-9]{3})',2)

此时返回值为 第2个括号括起来的匹配,即([0-9]{3}) 匹配到的 333

regexp_extract('【e往无前】亚索您已掉线333天,封号666天','(^【.*】).*?([0-9]{3})',0)

此时由于最后指定了0,即输出所有匹配,所以最后返回值为 【e往无前】亚索您已掉线333

2    测试数据构建

以上例子基本可以说明此函数的用法
为了进行更多演示,我在hive中创建了一个测试表,并构建了一些数据。

# 创建一个新的测试表,表中只有2个字段:电话号码 和 短信内容
hive -e"
CREATE TABLE test_aaa (  
  dest_number string,
  content string
)
stored as orc"

构建一些数据并导入

hive -e"
INSERT INTO test_aaa (dest_number,content) VALUES 
('17300001111','【草结笔记】您好,您的验证码是666666,退订回T'),
('17300001111','【e往无前】亚索您好,您的验证码是666666,退订回T'),
('17300001111','【小蘑菇】提莫您好,您今日复活次数为222333,下次活得久一点哦~'),
('15600001111','【我从不妥协】男刀锋您好,您的验证码:456144,感谢购买我店的拖鞋,路途愉快'),
('15600001111','【飞天锡纸螂】卡兹克您好,感谢购买星噬,您的验证码:666666,别给其他人看哦,退订回T'),
('15600001111','【e往无前】亚索您好,您的电刀正申请退货,验证码是666666'),
('13600001111','【大大太阳】您的验证码为123456,欢迎光临~'),
('18700001111','【大郎足浴城】欢迎注册会员,您的验证码是222333'),
('18700001111','【大郎足浴城】您好,本次您共消费222333元,期待下次光临~'),
('17300001111','【e往无前】亚索您好,验证码是666666,别再浪了')"

image.png

3    更多具体实例演示

1)  基于 号码、签名、验证码 分组

hive -e " 
select 
dest_number,
regexp_extract(content,'(^【.*】).*([0-9]{6})',1),
regexp_extract(content,'(^【.*】).*([0-9]{6})',2),
count(1) as total
from test_aaa
where content like '%验证码%'
group by dest_number,
regexp_extract(content,'(^【.*】).*([0-9]{6})',1), 
regexp_extract(content,'(^【.*】).*([0-9]{6})',2) 
order by  total  desc 
"

image.png

2)根据号码、可能的人名(称谓)分组

hive -e " select 
dest_number,
regexp_extract(content,'^【.*】(.*)您好',1),
count(1) as total
from test_aaa
where content like '%您好%'
group by dest_number,
regexp_extract(content,'^【.*】(.*)您好',1)
order by  total  desc "

image.png

3)根据号码、验证码分组

hive -e " select 
dest_number,
regexp_extract(content,'^【.*】.*([0-9]{6})',1),
count(1) as total
from test_aaa
where content like '%验证码%'
group by dest_number,
regexp_extract(content,'^【.*】.*([0-9]{6})',1)
order by  total  desc "

image.png

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注