Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10326536
  • 博文数量: 1669
  • 博客积分: 16831
  • 博客等级: 上将
  • 技术积分: 12594
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-25 07:23
个人简介

柔中带刚,刚中带柔,淫荡中富含柔和,刚猛中荡漾风骚,无坚不摧,无孔不入!

文章分类

全部博文(1669)

文章存档

2023年(4)

2022年(1)

2021年(10)

2020年(24)

2019年(4)

2018年(19)

2017年(66)

2016年(60)

2015年(49)

2014年(201)

2013年(221)

2012年(638)

2011年(372)

分类: LINUX

2013-11-27 15:17:48

正则表达式
2012-01-05 11:15:19
标签:正则表达式 shell 休闲 职场
版权声明:原创作品,如需转载,请与作者联系。否则将追究法律责任。
?这是一篇关于正则表达式的文档,如果你是Linux系统管理员,那么你一定离不开它(正则表达式)了, 
它可能出现在 grep/more/less/man/vi(m)/sed/awk/apache/nginx/haproxy 等等与linux 系统相关的地方,所以掌握正则表达式对于linux系统管理员很重要! 
 
 
一 什么是正则表达式? 
正则表达式是一种表示方式,让你可以查找匹配特定规则的文本 
 
二 正则表达式分两类 
1 BRE 基本正则表达式(Basic Regular Expression) 
2 ERE 扩展正则表达式(Extended Regular Expression) 
 
三 正则表达式由两部分组成 
正则表达式由两部分组成,一般字符与特殊字符 
1 一般字符,指的是没有任何特殊意义的字符,比如 abcdef123456等等用于表示其自身 
2 特殊字符,又称为元字符(metacharacter),见下表  
POSIX BRE 与 ERE 元字符表
字符     BRE/ERE   模式含义 
\        两者均可   关闭后边元字符的特殊意义 
.          :        匹配任意单个字符,但换行符除外 
*          :        匹配在它之前的重复任意次数的单个字符(包括0次,没有匹配) 
^          :        匹配紧接着的正则表达式,在行手或者字符串的起始处 
$          :        匹配前面的正则表达式,在行尾后者字符串结尾处 
[...]      :        匹配方括号内的任意字符,方括号内包含 - 连字符表示范围,^(第一位)表示取反 
\{n,m\}    BRE      区间表达式,匹配在它前面的单个字符重复区间次数,1至9次;5次;1,至少1次 
\( \)      BRE      后向引用,第一步将子表达式放在 \( 与 \)里,最多9个子表达式 
\n         BRE      后向引用,第二步使用匹配的子表达式,如 \1,后向引用用于查找重复字,以及匹配引号时特别好用,如\(["']\).*\1,匹配单引号或者双引号括起来的子. 
{n,m}      ERE      区间表达式与BRE相比少了反斜杠 
+          ERE      匹配前面的正则表达式的一次或者多次 
?          ERE      匹配前面的正则表达式的一次或者零次 
|          ERE      匹配|符号前或者后的正则表达式 
()         ERE      匹配使用括号括起来的正则表达式群  


四 正则表达式的优先级 
正则表达式的优先级,指的是某个运算符根据优先级高低,将优先处理
1 BRE 优先级(由高至低) 
运算符               含义 
[..] [==] [::]      用于字符排序的方括号符号 
\metacharacter   转义的元字符 
[ ]                方括号表达式 
\( \) \digit     子表达式与后向引用 
* \{ \}            重复前置的单个字符 
无符号             连续的字符 
^ $               锚点 
  
2 ERE 优先级(由高至低) 
运算符              含义 
[..] [==] [::]     用于字符排序的方括号符号 
\metacharacter   转义的元字符 
[ ]                方括号表达式 
( )                分组 
* + ? {}           重复前置的正则表达式 
无符号             连续的字符 
^ $                锚点 
|                  交替  


五 BRE 与 ERE 的不同 
BRE 与 ERE 在大多数的元字符与功能应用上几乎是完全一致的,但是ERE里有些元字符看起来与BRE类似,却具有完全不同的意义 
1 匹配单个字符; 
ERE与BRE基本一致,比如一般字符,用于转义的反斜杠,以及方括号表达式 
2 ERE中不存在后向引用; 
圆括号在ERE中表示分组,而\( \)在ERE中表示匹配左括号与右括号 
3 匹配单个表达式与多个正则表达式 
ERE在匹配多字符这方面与BRE有很明显的不同(*处理方式上除外),比如 区间表达式不在需要使用反斜杠,而 ? 与 + 元字符可以更细腻的匹配控制 
4 BRE中没有交替与分组 
与BRE不同ERE中拥有交替字符"|",用于匹配多个字符序列,比如 one|two|three|four ; 
同上,ERE拥有分组"()",用于表达式群,比如 (one)+ 用于匹配一个或多个连续的one ; 
组合使用,如 this is (one|two) 或者 this is (one|two)* 匹配0个或多个one 或者 two; 
5 停驻文本匹配(锚点) 
"^"与"$" 在 BRE与 ERE表示的意义是相同的,需要注意的是它们在方括号表达式中将会失去它们的特殊意义; 
组合使用,如 this is ^(one|two)$ 匹配one 或者 two  
 
六 额外的GNU表达式运算符
运算符           含义 
\w            匹配任何单词 
\W            匹配任何非单词 
\< \>           匹配单词的起始或结尾 
\b            匹配单词的起始或结尾处,所找到的空字符串  
..... 


  七 简单例子
1 sed 
sed -r 's\|[ ]*//g' 
sed -r 's/[ ]+//g;s/^\||\|$//g' variables      (注意 g 全局替换,如果不是用g 将只匹配每行的第一个) 
sed -r 's/[ ]+//g;s/(^\|)|(\|$)//g' variables   (注意 ()分组 与没有使用括号分组,完成的功能一样) 
sed -r 's/\|[ ]//g;s/[ ]*\|$//g' variables 
sed -r 's/([ ]+)?\|//g;s/ //;/\+/d' variables    
sed -re 's/(\|)//g' variables | sed -e 's/[ ]\{2,\}/ /g'  | sed -e '/^\+.*/d' 
sed -rf sed.sed variables  
cat sed.sed  
s/(\|)//g 
s/[ ]{2,}/ /g 
/^\+.*/d  
s/^( )|( )$//g 
 
2 vim 
:10,$ s/^[\t]*/ /            #行头所有换行符,用空格替换 
:10,30 s/^[ ]*/ /            #行头有多个空格,用一个空格替换 
:10,30 g/^ *$/d              #删除空行 
:10,20 s/[#].*/ /            ##号后边的任意位字符串,用一个空格替换 
:6,9 s/^[ ]//                #行头空格删掉! 
:1,$ s/\\n//                 #\n 删掉! 
:1,$ s/^[ ]// 
:10,20 s/[ ]\{2,\}//         #重复两次以上的空格,删掉! 
:7,20 s/^/echo "/ 
:7,20 s#$#\" >> /etc/rsyncd.conf# 分隔符是#,每行后添加 " >> /etc/rsyncd.conf 
:6,20 s/^/  /                #行头添加俩个空格,注意 中间有俩空格! 
:% s/^/#/g                   #每行前添加#号,如果每行尾添加则^变成$即可,%表示全文! 
 
:% s/\(\d\+\.\)\{3\}\d\+//g  #去掉 ip 地址(10.0.0.1) 
# 1. #!/bin/sh                #空白为 空格 
 ..... 
                                                   31. done  #空白为 tab 
:% s/^\s\{2,\}\d\+\.//g      #替换开头为空白或者tab ifs字符至少重复两次以上,接数字至少重复一次,接.号,全局替换   
# [url]com[/url]             
:% s#\[url\]\|\[/url\]##g    #替换 [url]或者[/url],注意 \| 表示或者  
 sed 杂记 20120606
[root@linux ~]# sed [-nefr] [动作] 
参数∶ 
-n  ∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 
      的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过 
      sed 特殊处理的那一行(或者动作)才会被列出来。 
-e  ∶直接在指令列模式上进行 sed 的动作编辑; 
-f  ∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的 
      sed 动作; 
-r  ∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法) 
-i  ∶直接修改读取的档案内容,而不是由萤幕输出。 
 
动作说明∶  [n1[,n2]]function 
n1, n2 ∶不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作 
         是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』 
 
function 有底下这些咚咚∶ 
a   ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~ 
i   ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行); 
c   ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行! 
d   ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚; 
p   ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~ 
s   ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配 
      正规表示法!例如 1,20s/old/new/g 就是啦! 
 
sed替换(WWW换成WEB) 
 
sed -ri 's/(COMPILE_INITS=).*/\10/' /install/ghostscript-8.63/Makefile (选项 -r 使用扩展正则表达式) 
 
sed -i 's/WWW/WEB/' dd.txt  (匹配 WWW 用 WEB代替) 
 
sed -i "s/^/''/g" one.txt   (注意 单引号与双引号,匹配每一行,把'' 添加到 行头部!) 
 
sed -i 's/.*index.html/DirectoryIndex index.html index.htm index.php/' /usr/local/apache/conf/httpd.conf 
sed -i '/AddType application\/x-gzip .gz .tgz/a\    AddType application\/x-httpd-php .php' /usr/local/apache/conf/httpd.conf    
   (注意 a\  在匹配这行之下添加一行!) 
sed -i '/export/a export PATH=$PATH:/usr/local/apache/bin' /etc/profile (别忘了 source /etc/profile) 
 
sed -n '/.*index.html/p' /usr/local/apache/conf/httpd.conf  (.*捡破烂模式) 
sed -n '/\/usr\/local.*\/bin/p' /etc/profile 
sed -i '/\/usr\/local.*\/bin/d' /etc/profile 
sed -n '/\/usr\/local\/.*/p' /etc/ld.so.conf 
 
sed -n '/bz-clone/p' /etc/hosts 
127.0.0.1bz-clone.test.com bz-clone localhost.localdomain localhost 
sed -i 's/bz-clone/cl3/g' /etc/hosts                         (注意 g 全局替换,如果不是用g 将只匹配每行的第一个) 
127.0.0.1cl3.test.com cl3 localhost.localdomain localhost 
 
sed -n 's/^#/shell>/p' sed.txt                                ()  
sed -n 's/^#/shell>/p' sed.txt 
sed -i 's/^#/shell>/' sed.txt 
 
sed -n '/^ $/p' sed.txt                                       
sed -n '/^ $/d' sed.txt                                       (注意 d 删除匹配这行) 
sed -r '/^sda/d' test1                                        d 删除^sda行 
sed -i '/^ $/d' sed.txt  
 
sed -n '/shell>/p' sed.txt 
sed '/shell>/i\ ' sed.txt 
sed -i '/shell>/i\ ' sed.txt                                  (注意 i\ 在匹配这行之上添加一行!) 
 
sed '1 d' test 
sed '1,2 d' test  
 
sed -rn 's/[0-9 \t]+//p' a.txt 
bbb        [ESXI]        10.0.0.1                10.0.0.2        DELL R910        SJHL        E7520*1.86GHz*4/300G*4/32G 
 
 
| Uptime                     | 325453     | 
| Uptime_since_flush_status  | 325453     | 
sed -r 's\|[ ]*//g' 
sed -r 's/[ ]+//g;s/^\||\|$//g' variables      (注意 g 全局替换,如果不是用g 将只匹配每行的第一个) 
sed -r 's/[ ]+//g;s/(^\|)|(\|$)//g' variables   (注意 ()分组 与没有使用括号分组,完成的功能一样) 
sed -r 's/\|[ ]//g;s/[ ]*\|$//g' variables 
sed -r 's/([ ]+)?\|//g;s/ //;/\+/d' variables    
sed -re 's/(\|)//g' variables | sed -e 's/[ ]\{2,\}/ /g'  | sed -e '/^\+.*/d' 
sed -rf sed.sed variables  
cat sed.sed  
s/(\|)//g 
s/[ ]{2,}/ /g 
/^\+.*/d  
s/^( )|( )$//g 
 
(感慨 ) 
sed -in '$d' /etc/rc.local          (注意 $ 最后一行) 
sed -r 's/(1.)|(2.)//g' en.txt | sort -n > tmp 
sed '/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile (这不是我想要的,在每一个export行,添加新的) 
sed '61,/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile (61, 为限定第61行) 
sed '$,/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile  (注意 $ 最后一行) 
sed -i '$ a\/usr/local/apr-util/lib' /etc/ld.so.conf                         (在最后一行添加一行文本) 
sed -ri '/^$/d;s/(^[ \t]+)//g;' /var/www/rsync/rsync_file.list               #-r拓展正则表达式,-i直接替换 
 
本文出自 “dongnan” 博客,转载请与作者联系!
阅读(810) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~