正则匹配详解

1. 元字符

字符 描述 应用
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符 ‘n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\’ 匹配 “” 而 “(” 则匹配 “(”。
. 匹配除换行符之外的任何单字符
^ 匹配输入字符串的开始 例如 ^a ,表示 字符串必须以a开头,才会继续匹配,如果不是以a开始,则返回空
$ 表示匹配字符串的结尾 例如 a$ ,表示 字符串必须以a结尾,如果不是以a结尾,则返回空
\b 匹配一个单词边界 例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\s 匹配所有空白符,包括换行
\S 匹配非空白符,不包括换行
\w 匹配字母、数字、下划线或汉字
\d 表示匹配一个数字字符,等同于[0-9]
\D 表示匹配一个非数字字符,等同于 [^0-9]
| 表示 或 a|b 表示匹配 a 或者b
[^] 表示不匹配集合中的任何元素 [^0-9] 表示匹配非数字字符, [^a-zA-Z] 表示匹配非英文字符
[] 表示匹配集合中的任何一个元素 [abc] 表示匹配a、b、c 三个元素中的一个, [a-z] 表示 匹配任意小写英文字符,[A-Z] 表示匹配任意大写英文字符,[0-9]表示匹配任意一个数字
() 标记一个子表达式的开始和结束位置。要匹配这些字符,请使用 \( 和 \)

2. 重复限定符

字符 功能描述 应用
* 匹配前一个位置的字符0次或多次 ba* 可以匹配 b,ba,baa,baaaa
+ 匹配前一个位置的字符1次或多次 ba* 可以匹配到 ba,baa,baaaa 但是匹配不到b
匹配前一个字符 0次或者1次,或指明一个非贪婪限定符 ba? 只能匹配到 b 、ba
{n} 表示匹配元素n次 a{3} 表示匹配的字符串为 aaa
{n,} 表示匹配元素大于等于n次 a{3} 表示匹配的字符串为 aaa,aaaa,aaaaaa
{n,m} 表示匹配字符次数在n和m次之间 a{3,5} 表示匹配的字符串为 aaa aaaa aaaaa 这三种

应用举例

-- 1.匹配8位数字的QQ号码:
^\d{8}$
--2. 匹配1开头11位数字的手机号码
^1\d{10}$
--3. 匹配以a开头的,0个或多个b结尾的字符串
 ^ab*$
-- 4. 匹配字符串中包含0到多个ab开头
 ^(ab)*
--5. 要匹配以(ab)开头
 ^(\(ab\))*
--6. 联通有130/131/132/155/156/185/186/145/176等号段,假如让我们匹配一个联通的号码
 ^((13[0-2])|(15[56])|(18[5-6])|145|176)\d{8}$

*+ 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

-- 字符串: string= "<h1>RUNOOB-菜鸟教程</h1> " 
<.*>   -- 匹配整个字符串

贪婪模式:在贪婪匹配下,.* 会匹配尽可能多的字符。使用 .* 的话就可以匹配任意长度的任意字符
上面的表达式匹配从开始小于符号 < 到关闭 h1 标记的大于符号 > 之间的所有内容。

<.*?>/  -- 只会匹配0或1次第一个< >中的内容    当.*?匹配到h1时,再往后的字符就是>,而>恰好可以匹配

非贪婪模式:非贪婪匹配就是尽可能匹配少的字符
如果您只需要匹配开始和结束 h1 标签,下面的非贪婪表达式只匹配 <h1>

<.*?>/   --只会匹配0或1次第一个< >中的内容    当.*?匹配到h1时,再往后的字符就是>,而>恰好可以匹配

**注:**但是这里需要注意,如果匹配的结果在字符结尾,.*?就有可能匹配不到任何结果了,因为他会尽可能匹配少的字符,例:

select regexp_extract('hello 1234567 world/python','he.*?(\\d).*rld/(.*?)',2)   -- 返回为空

select regexp_extract('hello 1234567 world/python','he.*?(\\d+).*rld/(.*)',2)  -- python

3. SQL 中正则匹配

3.1. 正则匹配

语法: regexp_extract(string subject, string pattern, int index)
说明: 将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。

---语法事例:
---regexp_extract  从起始位置开始匹配,当匹配到目标后,便停止匹配,返回index指定的group对应的字符串,每个() 表示一个group
SELECT regexp_extract('asbdad100-200喜马拉雅', '(\\d+)-(\\d+)', 1);  
           
---regexp_extract_all 从起始位置开始匹配,当匹配到目标后,仍然继续匹配,生成一个大的group,返回每个sub_group中index对应的字符串
SELECT regexp_extract_all('100-200, 300-400', '(\\d+)-(\\d+)', 1);   

3.2 正则替换

-- 使用字符串num替换匹配到的所有字符串
SELECT regexp_replace('100-200,300-400', '(\\d+)', 'num');    

3.3 应用实例

-- 1. regexp_replace用法
    -------- a. 截取字符串中的汉字部分
select regexp_replace('七夕节comming!来啦','([^\\u4E00-\\u9FA5]+)','')           --- 七夕节来啦
    -------- b. 截取字符串中字母和数字的部分
select regexp_replace('wo爱你123CHINA中国!','([^a-zA-Z0-9]+)','')              --- wo123CHINA
    -------- c. 将字符串中英文和数字的组合替换
SELECT regexp_replace('七夕节Coming666!','([a-z]+|[A-Z]+|[0-9]+)','') 

-- 2. regexp_extract用法
select regexp_extract('ab3.35_52-36_53-34_51.1063ef','(.*\\.)(\\d+.*\\d)(\\..*)',2)
select regexp_extract('七夕节coming666','([0-9]+)',1)             ---- 666
select regexp_extract('152天内有67天无通话记录','([0-9]+).*([0-9]+)',1) .   ----- 152
  • 去除字段里包含”地域“的标签
    正则匹配详解
select
    id,
    -- 相似应用: transfrom   filter
    regexp_replace(last_30d_ai_label_play_map,'(地域[^,]*,)|(,地域[^,]*\\d)|(地域[^,]*\\d$)','') as last_30d_ai_label_play_map
from xxx where last_30d_ai_label_play_map 
like "%地域%"
as res;
  • 使用transfrom 函数,处理数据
    应用实例:数据中出现类似: 郑渊洁:1.0,好习惯:0.33,郑渊洁给孙女的好习惯书:十二生肖童话绘本:0.75,孙女:0.67 的脏数据
select 
    id,
    nlp_labels_intros,
    concat_ws(',',transform(split(nlp_labels_intros,','), x -> if(size(split(x,':'))=3, concat(split(x,':')[0],split(x,':')[1],':',split(x,':')[2]) , x))) as label
from xxxx 
  • 提取各个画像对应的标签和权重
    正则匹配详解
select 
    cast( album_id as string) as album_id ,
    -- 使用非贪婪匹配模式
    split(regexp_replace(regexp_extract_all(get_json_object(label_group, '$.labels_ai'),'(t".")(.*?)(})',2 ),'\\]|\\[|","w"','') ,',') as nlp_labels_ai,  
    split(regexp_replace(regexp_extract_all(get_json_object(label_group, '$.labels_app'),'(t".")(.*?)(})',2 ),'\\]|\\[|","w"','') ,',') as nlp_labels_app,
    split(regexp_replace(regexp_extract_all(get_json_object(label_group, '$.labels_conp'),'(t".")(.*?)(})',2 ),'\\]|\\[|","w"',''),',' ) as  nlp_labels_conp,
    split(regexp_replace(regexp_extract_all(get_json_object(label_group, '$.titles'),'(t".")(.*?)(})',2 ),'\\]|\\[|","w"',''),',') as nlp_labels_titles,
    split(regexp_replace(regexp_extract_all(get_json_object(label_group, '$.intros'),'(t".")(.*?)(})',2 ),'\\]|\\[|","w"','') ,',') as  nlp_labels_intros,
    '$current(yyyyMMdd,-1)' as dt
from xxxxx
as res;

python 正则表达式

sublime中正则表达式的使用:
正则匹配详解

上一篇:Kubernetes – Google分布式容器技术初体验


下一篇:asp net core 跨平台初体验