一、元字符
(摘自百度百科)
符号 | 描述 |
---|---|
. | 匹配除“\n”和"\r"之外的任何单个字符 |
[a-z] | 字符范围,匹配指定范围内的任意字符 |
[0-9] | 数字集合,匹配0到9的任意数字 |
[xyz] | 字符集合,匹配所包含的任意一个字符,x、y、z可为任意字符,[]内()无意义 |
| | 或,[x|y]匹配x或y,等价于[xy] |
^ | ^仅在[]内表示取反,如[^xyz] 为不包含x或y或z的任意字符,[^a-z]为不含包英文字母a到z的任意字符, ^[0-9]为任意非数字 |
\d | 匹配一个数字字符,等价于[0-9] |
\D | 匹配一个非数字字符,等价于[^0-9] ,将字母大写表示在原意下取反,下同 |
\w | 匹配包括下划线的任何单词字符,等价于[A-Za-z0-9_](经核验非英文字符已不受影响,完全等价) |
\W | 匹配任何非单词字符。等价于[^A-Za-z0-9_] |
\cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符 |
\f | 匹配一个换页符,等价于\x0c和\cL |
\n | 匹配一个换行符,等价于\x0a和\cJ |
\r | 匹配一个回车符,等价于\x0d和\cM |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v]。 |
\S | 匹配任何可见字符,等价于[^ \f\n\r\t\v] 。 |
\t | 匹配一个制表符,等价于\x09和\cI |
\v | 匹配一个垂直制表符,等价于\x0b和\cK |
* | 匹配前面的子表达式任意次 |
+ | 匹配前面的子表达式一次或多次(大于等于1次) |
? | 匹配前面的子表达式零次或一次 ;当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串 |
{n} | 匹配确定的n次 |
{n,} | 至少匹配n次 |
^ | 匹配输入字行首或取反 |
$ | 匹配输入行尾 |
\b | 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的) |
\B | 匹配非单词边界 |
(?:pattern) | 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用 |
(?=pattern) | 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用 |
(?!pattern) | 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用 |
(?<=pattern) | 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反 |
(?<!pattern) | 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反 |
二、案例
hive正则可以在regexp_extract、regexp_replace等函数中使用,具体案例如下:
(以下案例如要为方法展示,未必是最优解,如有疏漏,欢迎斧正)
案例一:简单匹配电话号码(涉及位置、循环匹配)
匹配出电话号码,电话号码必须1开头且为11位,即表中第1、3、5条记录
TEl | autoid |
---|---|
185****2546 | 1 |
182****25466 | 2 |
150****6623 | 3 |
550****9542 | 4 |
136****7053 | 5 |
select regexp_extract(lower(tel),'(^1[3-9]\\d{9}$)',0) as tel_number;
关键代码解读:
1)国内电话号码已1开头,且第二位在3-9之间,所以有^1[3-9]
2)除上述两位数字外,其余还有9位,所以有\d{9},且以加上结尾符号$
3)可以使用或条件进行更加严格的手机号匹配
案例二:匹配系统型号(涉及或、循环、非获取匹配)
匹配系统名称,安卓系统版本大于5.0,IOS系统版本大于6.0,即表中第2、4、5条记录
value | autoid |
---|---|
android5.1.5 | 1 |
android7.1.2 | 2 |
ios6.6 | 3 |
ios8.1 | 4 |
ios11.4 | 5 |
select regexp_extract(lower(value),'((android)(?=([6-9]|[1-9][0-9])[.0-9]+))|((ios)(?=([8-9]|[1-9][0-9])[.0-9]+))',0) as osname;
关键代码解读:
1)要同时匹配android和ios,所以使用“|”做或处理
2)需要匹配系统名称但不需要系统版本,所以使用非获取匹配(?=pattern),即查找字符但不获取
3)因安卓系统版本大于5.0,IOS系统版本大于6,所以android后接6-9或者10-99,ios同理
4)因系统版本有子版本,对点加数字([.0-9])做贪婪匹配
案例三:匹配多次出现字符(反向引用)
某投球活动,有四个命中点,用户第一次投中某命中点后,后续至少再投中该点两次,一共四次机会,匹配出所有完成任务的记录,即第1、4条记录
result | autoid |
---|---|
aaba | 1 |
abac | 2 |
bdab | 3 |
dddd | 4 |
cdab | 5 |
select regexp_extract(result,'(^[a-d]).?\\1.?\\1.?',0) as tel_number;
关键代码解读:
1)通过()可以将匹配到的内容作为一个整体,该过程即为捕获组,捕获组中的内容在正则表达式内部进行引用即反向引用
2)\1表示第一个()匹配到的内容,如果有第二个()则可用\2表示第二个()匹配到的内容,后续同理