前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux工具——神奇的正则表达式

linux工具——神奇的正则表达式

作者头像
数据仓库践行者
发布2022-03-15 08:35:35
6930
发布2022-03-15 08:35:35
举报
文章被收录于专栏:数据仓库践行者

Hi, 我是小萝卜算子

近来有小伙伴私信我,说grep配合正则更无敌,但是正则总记不住,能不能整一个简单的参考,有需求必须安排一章

一、介绍

正则表达式是对字符串和特殊字符操作的一种逻辑公式,做开发的或多或少都接触过正则,其在检索匹配和替换领域能发挥超乎寻常的作用,掌握好正则表达式往往能达到事半功倍的效果,详情请看下文

二、常用字符

匹配符 (只列出常用的)

^: 匹配字符串开始,在方括号内标识非,即排除

$: 匹配字符串结束

[]: 匹配括号中的任一字符  [a-z] 匹配a-z ; [^A-Z] 不匹配A-Z;

. : 匹配除换行符之外所有的数据

\d(D):  匹配(非)数字 

\w(W):  匹配(非)数字、字母以及下滑线

\s(S) : 匹配(非)空格、换行符

\r -- \n -- \t:  回车 -- 换行 -- 制表符

\b(B):  匹配单词的(非)边界

eg:

匹配以a或者b或者c开头的数据

echo 'abcd' | grep -P '^(a|b|c)'

因为是单字符所以还可改为

echo 'abcd' | grep -P '^[abc]'

限定符

{n}: 次数=n

{n,}: 次数>=n 

{n,m}:   m>=次数>=n 

*:  次数>=0 

+:  次数>=1 

?:  0或者1(跟在限定符后表示非贪婪)

eg:

匹配最少连续三个ab组成的字符

echo 'mmababcdabababnn' | grep -P '(ab){3,}'

可以看出前面连续两个ab组成的字符没被匹配到

echo 'mmababcdabababnn' | grep -oP 'm+?'

m+是贪婪模式,尽可能多的匹配m数量,但是加了个?,则表示非贪婪

无敌的小括号

( ): 分组 

(?:pattern): 非获取分组

(?=pattern): 非获取匹配,正向肯定预查

(?!pattern): 非获取匹配,正向否定预查

(?<=pattern): 非获取匹配,反向肯定预查

(?<!pattern): 非获取匹配,反向否定预查

eg:

获取版本号

如 version1.23.4

echo 'version1.23.4' | grep -oP "(?<=version)[\d.]+"

(?<=version) 反向肯定预查,代表以version开头,但是并不获取此数据

特殊的字符

\ :转义字符

| :或  a|b 

eg:

获取 包含 * 或者 ^ 或者 + 的数据

echo "sdf*sdf^ssdfs\

当然更简洁的还是使用[]

echo "sdf*sdf^ssdfs\

因为在[]内 ^ 有特殊意义,所以要转义,如果放在后面,则可省略转义

echo "sdf*sdf^ssdfs\

三、应用实例

注:以下例子是用的grep + perl, 其他的正则可能会有些微差别

新建文本 tmp.txt 内容如下:

1:获取全数字内容 (纯数字)

cat tmp.txt | grep -oP '^[\d]+$'

2:获取方括号内容--非获取匹配(爬虫之类的html 标签之间内容也是类似)

cat tmp.txt | grep -oP '(?<=\[)[^]]*'

3:查出所有非空行(全空格也排除)和非注释行

sed '/^\s*#/d;/^\s*$/d' tmp.txt

sed -e '/^\s*#/d' -e '/^\s*$/d' tmp.txt

sed '/^\s*#\|^\s*$/d' tmp.txt

awk '!/^\s*#|^\s*$/' tmp.txt

grep -vP '^\s*#|^\s*$' tmp.txt

4:找出正数部分为5位及以内,小数部分为3位及以内的数据(此为线上真实例子)

cat tmp.txt | grep -oP '^(0|[1-9]\d{0,4})(\.\d{1,3})?$'

5:找出带下划线的数据,并转成驼峰(比较常用)

sed -n 's/_\(.\)/\u\1/gp' tmp.txt

update_password 修改为 updatePassword

6:交换方括号和大括号内容并输出(主要想让大家了解分组的用法)

sed 's/\([^][]*\)\(\].*{\)\([^}]*\)/\3\2\1/' tmp.txt

四、密码校验详解(手把手教大家)

需求:对用户输入的密码进行校验,要求只能含有数字,小写字母,大写字母

而且必须包含三种类型中的最少两种,且长度在6--10位

正常版:

1: 首先想到只能含有数字大小写字母,且6到10位

根据前面介绍的正则情况,可以限定 ^[\da-zA-Z]{6,10}$

2: 要求含3种类型中的至少两种,比如含有数字和小写字母,但是因为顺序不定所以可罗列为:[\d].*[a-z]|[a-z].*[\d]

那么把所有要求的情况展示出来,最终的结果是

代码语言:javascript
复制
echo 'password' | grep -P '[\da-zA-Z]{6,10}' | grep -P '[\d].*[a-z]|[a-z].*[\d]|[\d].*[A-Z]|[A-Z].*[\d]|[A-Z].*[a-z]|[a-z].*[A-Z]'

简洁版:

有没有觉得上面的方式有点怪怪的

首先是分两步验证

其次是如果情况很多的话罗列起来是不是很吓人,而且容易遗漏

有没有一种简单又实用的正则呢

答案当然是肯定的,这里就用到了零宽断言

当然基本要求还是固定的

^[\da-zA-Z]{6,10}$

判断是否包含小写字母和数字则

(?=.*[\d])(?=.*[a-z])不用区分先后顺

那么完整的结构为

代码语言:javascript
复制
echo 'password' | grep -P '(?=.*[\d])(?=.*[a-z])|(?=.*[A-Z])(?=.*[a-z])|(?=.*[\d])(?=.*[A-Z])^[\da-zA-Z]{6,10}$'

是不是很神奇呢!!!

其实掌握正则很简单,就是 匹配字符+限定符,以尽可能少的字符达到想要的结果,熟能生巧,想彻底掌握,还是需要多多练习哇。。。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库践行者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档