练习正则表达式

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

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

字符匹配      
         .(点)一个任意字符,回车符换行符除外
         [ ]匹配所包含的任意一个字符
         [^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

相关推荐

  • 作业–文本处理工具

    1、找出ifconfig命令结果中本机的所有IPv4地址。 [root@liang ~]# ifconfig        #centos6下 eth0      Link encap:Et…

    Linux干货 2016-08-10
  • 20161021第6天作业

    20161021第6天作业 1、将PATH变量每个目录显示在独立的一行  echo "$PATH" |tr ':' '\n' 2、将指定文件中0-9分别替代成a-j tr '0-9' 'a-j' <文件 3、将文件中每个单词(由字母组成)显示在…

    Linux干货 2016-10-23
  • 配置NTP服务器

    配置NTP时间服务器 一.安装ntp软件 1.检查是否安装了ntp相关包。 rpm -qa | grep ntp 2.安装ntp软件。 yum -y install ntp 二.参数讲解 ignore  :关闭所有的 NTP 联机服务 nomodify:客户端不能更改服务端的时间参数,但是客户端可以通过服务端进行网络校时。 notrust :客户端…

    Linux干货 2016-10-30
  • linux快捷键

    $ 用法 $变量名 表引用变量的值 $()或(单引号) 表示引用命令执行的结果 $[] 表示运算 ${变量名} 或"$变量名" 当变量名的起止不分明时,用来划定变量名的范围,同时引用变量。 {} 用法 {a..z} 表示引用指定范围的字母 {1..9999} 表示引用指定范围的数字​ {1,3,5} 表示分别引用每一个字符 TAB 用法 …

    Linux干货 2017-07-13
  • ☞Web服务器之apache

    Web服务器之apache http协议 telnet的使用 curl命令 httpd的相关配置 welcome.conf — 403 forbidden 修改监听的端口和地址 保持连接 DSO 定义物理主机站点文档 资源访问授权 路径别名Alias 本地httpd-manual 开启status 日志设定 虚拟主机 基于用户的访问控制 httpd压力测试 …

    Linux干货 2016-10-08
  • shell脚本编写-3

    1、for循环 for 变量名 in  列表;do 循环体 done 执行机制:依次将列表中元素赋值给“变量名”;每次赋值后即执一次循环体;直到列表中元素耗尽循环结束 列表生成方式: (1) 直接给出列表 (2) 整数列表: (a){start..end} (b) $(seq [start [step]] end)  (3) 返回列表的命…

    Linux干货 2016-08-18