练习正则表达式

    正则表达式可以通过元字符(规则)来匹配查找相关的的字符集合。他与通配符是有区别的。而且相关的使用工具对正则表示的元字符的是有区别的。

    首先我们先来了解下常用的元字符及含义(并不是所有的元字符)

字符匹配      
         .(点)一个任意字符,回车符换行符除外
         [ ]匹配所包含的任意一个字符
         [^xyz]负值字符集合。匹配未包含的任意字符。        
         [a-z]字符范围。匹配指定范围内的任意字符。        
             注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围;        
             如果出字符组的开头,则只能表示连字符本身.        
         [^a-z]^表示取反;匹配不在指定范围内的任意一个字符。        
         [:space:] 一个空白字符        
         [:punct:] 一个(所有)标点符号        
         [:lower:] 一个小写字母 [a-z]  不能写成[z-a]        
         [:upper:] 一个大写字母 [A-Z]        
         [:digit:]  一个数字    [0-9]        
         [:alnum:] 一个数字和字母 [A-Z0-9a-z]        
         [:alpha:]  一个大小写字母 [a-zA-Z]
位置锚定
        ^ 匹配输入字符串的开始位置。行首  写在左侧
        $匹配输入字符串的结束位置。写在行尾
        \b匹配一个单词边界,
        \B匹配非单词边界。
        \< \>匹配词(word)的开始(\<)和结束(\>)。
重叠次数
        *匹配前面的子表达式、字符零次或多次(大于等于0次)。
        +匹配前面的子表达式一次或多次(大于等于1次)
        ?匹配前面的子表达式零次或一次。(基本表达式需要转意 \)
        {n}前面字符匹配n次。 (基本表达式需要转意 \)
        {n,}至少匹配n次,至多不管啊   (基本表达式需要转意 \)
        {n,m}其中n<=m。最少匹配n次且最多匹配m次。  (基本表达式需要转意 \ )
特殊功能
        ( ) 将 \( 和 \) 之间的表达式定义为“组”(group),并将匹配到的字符保存到一个临时区域
       (一个正则表达式中最多可以保存9个),可以用 \1 到\9 的符号来引用。分组中的模式匹配到的内容,
        可由正则表达式引擎记忆在内存中,之后可被引用有编号:自左而后的左括号,以及与其匹配右括号
        (基本表达式需要转意 \)
        \n引用第n个括号所匹配到的内容,而非模式本身
        |将两个匹配条件进行逻辑“或”(Or)运算。扩展正则表达式
        \转义符号,把后面的字符特殊的转为普通,普通的转为特殊

   这上面的这些字符没有别的办法就是记住和理解,其实就是规则文字游戏并不是一开始接触时候的时候所认认为的那么难。重要的是先对单个元字符去实验下然后再去组合。综合而言正则表达式就是计算机所能识别的并被人类所能操作的一种语言,他有很多组合方式来实现你所想要的功能。

    使用正则表达式之前首先肯定是有需求或者说是目标,然后分析组合匹配规则。在这里我感觉还是使用扩展正则表达式的好,无需纠结。

    首先准备一串字符,我放在了/tmp/ceshi

    130 120 200 450 12 24 70 140 8000 30
    30 120 200 450 12 24 170 140 80
    78 30 1800 200 450 12 24 170 40 80
    30 1800 200 450 120 24 170 40 70 70 70
    389 30 1800 200 450 120 24 1000 40 70
    30 30 1800 200 450 120 24 1000 40 70
    130120 200 450122470140800030
    30120200450122417014080
    7830180020045012241704080
    3018002004501202417040707070
    3893018002004501202410004070
    303018002004501202410004070

 匹配下以30开头中间必须含有70的字符串:

    1、单个匹配以30为开头:需要做行首锚定^30

    2、单个含有70: 70 

    3、组合匹配需要注意中间30和70之间是可以经过任意字符的.*

    ^30.*70

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "^30.*70"
    30 120 200 450 12 24 170 140 80
    30 1800 200 450 120 24 170 40 70 70 70
    30 30 1800 200 450 120 24 1000 40 70
    30120200450122417014080
    3018002004501202417040707070
    303018002004501202410004070

   

 匹配下以30开头中间必须包含1800以70结尾的字符串:

    还是同样的步骤分析几个重要的点

    1、30开头:^30

    2、中间必须包含1800: 1800前后都有可能存在字符 .*1800.*

    3、以70结尾:70$

    ^30.*1800.*70$

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "^30.*1800.*70$"
    30 1800 200 450 120 24 170 40 70 70 70
    30 30 1800 200 450 120 24 1000 40 70
    3018002004501202417040707070
    303018002004501202410004070
    要求30后面需要跟一个空白字符呢?
    要求30后面需要跟上1或者3呢?   
    ^30[ ].*1800.*70$
    ^30[1|3].*1800.*70$

 再来试几个简单的实例

 1、要求70 至少出现2次最多出现3次

    我们需要用到{n,m}其中n<=m。最少匹配n次且最多匹配m次。

    70{2,3}是这样吗?我们来试试

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "70{2,3}"
    [root@zhuzw-centos6 tmp]# echo $?
    1

    执行错误了为什么呢?仔细看看元字符你会发现它们基本上都是针对单个字符.

    70{2,3}实际表示的意思应该是700|7000.

    那么我们如何匹配多个字符呢?这就用到了().

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(70){2,3}"
    3018002004501202417040707070

    这里需要注意下\n 匹配的是()里面的匹配处来的内容而不是里面的子表达式

    n从外圈开始计算,最外圈的为1

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(6(7(\<200\>)))*.*\3?.*[ ]70$"
    30 1800 200 450 120 24 170 40 70 70 70
    389 30 1800 200 450 120 24 1000 40 70
    30 30 1800 200 450 120 24 1000 40 70
    [root@zhuzw-centos6 tmp]# A400=200
    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(6(7(\<`echo A400`\>)))*.*\3?.*[ ]70$"
    30 1800 200 450 120 24 170 40 70 70 70
    389 30 1800 200 450 120 24 1000 40 70
    30 30 1800 200 450 120 24 1000 40 70

    2、+和?这两个元字符其实用法跟{n,m}是一样的

    +可以写成{1,}至少出现1次,m不赋值表示无限制,但是不许符合n的要求。

    ?可以写成{0,1}

    对于 \B  \b \< \>呢你可以把上面字符中被空白字符隔开的一组数字看成是一个单词。

    \B200\B  \b200\b \<200\> 的区别通过下面的匹配输出就能对比出来了。

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\B200\B"
    30120200450122417014080
    7830180020045012241704080
    3018002004501202417040707070
    3893018002004501202410004070
    303018002004501202410004070
    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\b200\b"
    130 120 200 450 12 24 70 140 8000 30
    30 120 200 450 12 24 170 140 80
    78 30 1800 200 450 12 24 170 40 80
    30 1800 200 450 120 24 170 40 70 70 70
    389 30 1800 200 450 120 24 1000 40 70
    30 30 1800 200 450 120 24 1000 40 70
    130120 200 450122470140800030
    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\<200\>"
    130 120 200 450 12 24 70 140 8000 30
    30 120 200 450 12 24 170 140 80
    78 30 1800 200 450 12 24 170 40 80
    30 1800 200 450 120 24 170 40 70 70 70
    389 30 1800 200 450 120 24 1000 40 70
    30 30 1800 200 450 120 24 1000 40 70
    130120 200 450122470140800030

最后呢我们来匹配下一个邮箱地址

邮箱的格式 zhuzw_1203@126.com

这是126的邮箱名字规则:6~18个字符,可使用字母、数字、下划线,需以字母开头

grep -E "^[[:alpha:]]([a-z]|[A-Z]|[0-9]|[_]){5,17}@([[:alnum:]]+[\.])+[[:alnum:]]+$"
"[[:alpha:]]([a-z]|[A-Z]|[0-9]|[_]){5,17}@([[:alnum:]]+[\.])+[[:alnum:]]+"

字母开头[[:alnum:]]

可使用字母、数字、下划线 :([a-z]|[A-Z]|[0-9]|[_])

6~18个字符:{5,17}注意因为前面已经有开头的字母占一位了

@:@ 

邮箱后缀格式126.com :  ([[:alnum:]]+[\.])+[[:alnum:]]+

    英文大小写数字字符至少出现一次,转义.这个符号;把这两个字表达式作为一个组至少出现一次;最后匹配一个英文大小写数字字符至少出现一次。分组的原因是可能会有126.com.cn  126.163.com.cn 这种格式的出现。

    好了写到这里正则表达式的笔记和分享暂告一段落。最后呢其实还是大家先去分析下我们的最终目标然后结合语法去写;目标明确才好去实现。

原创文章,作者:东郭先生,如若转载,请注明出处:http://www.178linux.com/3213

(0)
东郭先生东郭先生
上一篇 2015-04-15
下一篇 2015-04-15

相关推荐

  • 笔记

    命令 命令列表 alias 别名 bc 计算器 basename文件基本名 cp 复制 cd 进入文件夹 cat /proc/partition 查看硬盘的使用情况 cat /proc/meminfo 查看内存的使用情况 chvt 切换终端 chown改变文件的所属组 edj:chown -R www /etc/host clock 查询或设置硬件时间 ch…

    Linux干货 2017-05-25
  • Mariadb数据库复制系列(三):半同步复制

       实验三:半同步复制的实现 默认情况下,主从复制的结构中,主从节点之间复制操作是异步的,这样就有可能造成主从节点之间数据不一致的情况发生,所谓版同步复制就是指在一主多从的场景中,我们设定主节点与其中一个或多个从节点(一般是一个)的数据复制是同步进行的,从而保证了该从节点和主节点之间的数据的一致性。故当主节点发生故障时,就可以基于其他方式将该从节点提升为主…

    Linux干货 2016-11-24
  • redis主从复制(4)— client buffer

    1、 client buffer的设计 redis server以单进程的方式处理接收到的请求,而redis完成请求有些工作比较慢,比如网络IO和磁盘IO等比较慢的操作。redis为了提高处理客户端请求的响应时间,做了很多优化。比如网络io和磁盘io是异步完成、使用后台进程完成bgsave和bgrewriteaof工作,在server端为客户提供读buffe…

    Linux干货 2016-03-28
  • 初识

    CPU:运算器、控制器、寄存器、缓存 分区不能直接被访问,需要接口 磁盘0 第一分区  挂载mount      C 磁盘0 第一分区  挂载mount      C:\var 如果一个目录没有被分区单独挂载,那么其数据存储在父目录所对应的…

    2017-07-11
  • Linux系统文件管理

    1、Linux的文件类型:       –:普通文件;       d:目录文件;       b:块设备:     &nbsp…

    Linux干货 2016-08-04
  • N22-第九周作业

    1、写一个脚本,判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin);分别这两类用户的个数;通过字符串比较来实现; #!/bin/bash # declare -i log_user declare -i notlog_user while read&n…

    Linux干货 2016-10-24