【数据库】Hive SQL 正则表达式进阶二(regexp_extract函数进阶使用)

       在之前文章中(文章如下),小白有讲过正则的三个函数,替换、截取等操作。在工作中,又遇到了其他的问题,这里做一个进阶的讲解文章,欢迎遇到类似问题的小伙伴一起学习交流。

初级用法参照下面的文章

Hive SQL 正则表达式进阶一(regexp的三个函数)https://blog.csdn.net/Jarry_cm/article/details/87272189

场景一

有以下几种情况的数据,需要将15|后面的内容取出来,后面有可能是英文,有可能是数字,位置不固定。

我们看下几种SQL的形式:

第一种:

select regexp_extract('15|Range,16|5,31|369728,17|1',"(15\\|)(.*?)(,)",2) as r1,
       regexp_extract('16|5,15|30,31|369728,17|1',"(15\\|)(.*?)(,)",2) as r2,
       regexp_extract('16|5,31|369728,17|1,15|Range',"(15\\|)(.*?)(,)",2) as r3,
       regexp_extract('15|30',"(15\\|)(.*?)(,)",2) as r4

结果如下:前两种能解析出来,后两种解析不出

这是因为,后面两种没有逗号,所以是不匹配的

r1 r2 r3 r4
Range 30  

那有人会说,我把逗号去掉,数字变为1不就好了么,OK来试一下

第二种:这里需要注意一下  .*?  表示匹配任意字符到下一个符合条件的字符,这里把后面的逗号去掉了,那就从来都不会满足该条件,因此,无论哪种形式,第二个位置都不会匹配出来

看一下填1

select regexp_extract('15|Range,16|5,31|369728,17|1',"(15\\|)(.*?)",1) as r1,
       regexp_extract('16|5,15|30,31|369728,17|1',"(15\\|)(.*?)",1) as r2,
       regexp_extract('16|5,31|369728,17|1,15|Range',"(15\\|)(.*?)",1) as r3,
       regexp_extract('15|30',"(15\\|)(.*?)",1) as r4

结果:

r1 r2 r3 r4
15| 15| 15| 15|

 看一下填2

select regexp_extract('15|Range,16|5,31|369728,17|1',"(15\\|)(.*?)",2) as r1,
       regexp_extract('16|5,15|30,31|369728,17|1',"(15\\|)(.*?)",2) as r2,
       regexp_extract('16|5,31|369728,17|1,15|Range',"(15\\|)(.*?)",2) as r3,
       regexp_extract('15|30',"(15\\|)(.*?)",2) as r4

结果:

r1 r2 r3 r4
     

看一下填0,0是符合所有条件的结果,第二个永远遍历不完,所以结果和填1是一样的

select regexp_extract('15|Range,16|5,31|369728,17|1',"(15\\|)(.*?)",0) as r1,
       regexp_extract('16|5,15|30,31|369728,17|1',"(15\\|)(.*?)",0) as r2,
       regexp_extract('16|5,31|369728,17|1,15|Range',"(15\\|)(.*?)",0) as r3,
       regexp_extract('15|30',"(15\\|)(.*?)",0) as r4

结果:

r1 r2 r3 r4
15| 15| 15|

15|

 因此,这里们要分析,竖线后面有哪些形式,英文或者是数字,那么第二个匹配我们应该匹配英文或数据,那下面写法就可以达到目的了。

select regexp_extract('15|Range,16|5,31|369728,17|1',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r1,
       regexp_extract('16|5,15|30,31|369728,17|1',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r2,
       regexp_extract('16|5,31|369728,17|1,15|Range',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r3,
       regexp_extract('15|30',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r4,
       regexp_extract('15|Range',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r5,
       regexp_extract('16|5,15|Range,31|369728,17|1',"15\\|(([A-Za-z]{1,})|(\\d{1,}))",1) as r6
       

总的来说,正则中有很多小知识点,做正则时除了需要细心,掌握每种可能的情况,才能正确的解析。

发布了91 篇原创文章 · 获赞 125 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/Jarry_cm/article/details/103995093