正则表达式(二):子表达式及反向引用

1.子表达式

子表达式通常作为更长的表达式的一部分,子表达式可以作为单一的实体来使用。 子表达式由()来定义。前文说过,表示重复次数的元字符只能作用于紧挨着它的前一个字符,引入子表达式之后,就可以让子表达式作为一个整体重复多次。Python和Hive中都有语法帮助我们提取出子表达式匹配的内容。

Python版本:

import re
result=re.search(r'(\d{4})-(\d{8})','0571-68819999')
print(result.groups())

实验结果:

('0571', '68819999')

Hive版本:

select '0' as num, regexp_extract('0571-68819999','^(\\d{4})-(\\d{8})$',0) as result
union
select '1' as num, regexp_extract('0571-68819999','^(\\d{4})-(\\d{8})$',1) as result
union
select '2' as num, regexp_extract('0571-68819999','^(\\d{4})-(\\d{8})$',2) as result

代码结果如下:(从实验结果可以看出,Hive中分组的索引是从1开始的,0对应的是完整匹配

numresult
00571-68819999
10571
268819999

子表达式是支持嵌套的,但是嵌套之后各个表达式的索引会容易引起混乱。

Python版本:

import re
str_1='135-0577-2345'
match=re.search(r'(((\d{3})-(\d{4}))-(\d{4}))',str_1)
print(match.groups())

代码结果:

('135-0577-2345', '135-0577', '135', '0577', '2345')

从结果和其对应的索引关系可以看出,索引编号是从外到内,从左到右,深度优先

Hive版本:

select '1' as num, regexp_extract('135-0577-2345','(((\\d{3})-(\\d{4}))-(\\d{4}))',1) as result
union 
select '2' as num, regexp_extract('135-0577-2345','(((\\d{3})-(\\d{4}))-(\\d{4}))',2) as result
union 
select '3' as num, regexp_extract('135-0577-2345','(((\\d{3})-(\\d{4}))-(\\d{4}))',3) as result
union 
select '4' as num, regexp_extract('135-0577-2345','(((\\d{3})-(\\d{4}))-(\\d{4}))',4) as result
union 
select '5' as num, regexp_extract('135-0577-2345','(((\\d{3})-(\\d{4}))-(\\d{4}))',5) as result

代码结果如下:(Hive中的索引和Python中的索引顺序一致)

numresult
1135-0577-2345
2135-0577
3135
40577
52345

2. 反向引用

反向引用允许正则表达式模式引用之前匹配的结果。反向引用需要结合字表达式一起使用。这个主要用来匹配需要成对出现的模式。以一个Python程序为例(代码中的\1表示引用分组索引为1的匹配结果):

import re
str_1='<h1>helloworld</h1>'
str_2='<h1>pythonclass</h2>'
match_1=re.search(r'<(h[0-9])>\w*?</\1>',str_1)
print(match_1[0] if match_1 else 'null')
match_2=re.search(r'<(h[0-9])>\w*?</\1>',str_2)
print(match_2[0] if match_2 else 'null')

其结果如下:

<h1>helloworld</h1>
null

Hive和MySQL中也支持反向引用。注意,我用的MySQL8.0版本,在其他书上看到MySQL5版本可能是不支持反向引用的。

select '1' as num, '<h1>hello123world</h1>' regexp '<(h[1-6])>\\w+</\\1>' as result
union
select '2' as num, '<h1>hello123world</h2>' regexp '<(h[1-6])>\\w+</\\1>' as result

 Hive运行结果如下:

numresult
1true
2false

3. MySQL8.0中支持的正则表达式函数

NameDescription
regexp字符串中是否有与模式匹配的子串,如果有返回1或True,没有返回0或False。
not regexp将 regexp表达的结果置反。
regexp_like与regexp结果相同。
rlike与regexp结果相同。
regexp_instr返回字符串中与模式匹配的子串的开始索引位置,若没有子串与模式匹配,则返回0。
regexp_replace将字符串中与模式匹配的子串替换成其他字符串。
regexp_substr返回字符串中与模式匹配的子串。

regexp_like代码(MySQL中字符串索引从1开始):

select '1' as num,regexp_instr('hello123world456','[0-9]+') AS result
union all
-- 参数7用来指定开始搜索的位置,不写默认为1
select '2' as num,regexp_instr('hello123world456','[0-9]+',7) as result
union all
-- 参数2的作用:当字符串中有多个子串与模式匹配是时,定位到第2个与模式匹配的子串,返回该子串的起始索引
select '3' as num,regexp_instr('hello123world456','[0-9]+',1,2)as result
union all
select '4' as num,regexp_instr('hello123world456hello123','[0-9]+',1,3)as result

 结果如下:

numresult
16
27
314
422

 regexp_replace\substr()代码:

select '1' as num,regexp_replace('hello123world','[0-9]+',' ') as result
union ALL
select '2' as num,regexp_substr('hello123world','[0-9]+') as result

 结果如下:

numresult
1hello world
2123

 正则表达式(1):https://blog.csdn.net/yeshang_lady/article/details/99626016

转义字符:https://blog.csdn.net/yeshang_lady/article/details/100778418

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值