跳转至

Shell 正则表达式


2013-03-17 by dongnan

开始之前

如果你是Linux系统管理员,那么你工作中一定会用到正则表达式, 它可能出现在 grep/more/less/man/vi(m)/sed/awk 等命令中,所以掌握正则表达式对于Linux系统管理员很重要。

举个栗子

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

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地址为空
:% s/^\s\{2,\}\d\+\.//g      //替换开头为空白或者tab ifs字符至少重复两次以上,接数字至少重复一次,接.号            
:% s#\[url\]\|\[/url\]##g    //替换 或者,注意 \| 表示或者

什么是正则表达式?

正则表达式是一种表示方式,让你可以查找匹配特定规则的文本

正则表达式分类

BRE 基本正则表达式(Basic Regular Expression)。

ERE 扩展正则表达式(Extended Regular Expression)。

正则表达式组成

正则表达式由两部分组成,一般字符与特殊字符:

  • 一般字符,指的是没有任何特殊意义的字符,比如abc456等用于表示其自身。
  • 特殊字符,又称为元字符(metacharacter)。

元字符

字符     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      匹配使用括号括起来的正则表达式群

正则表达式优先级

正则表达式的优先级,指的是某个运算符根据优先级高低,将优先处理

BRE优先级(由高至低)

运算符               含义 
[..] [==] [::]      用于字符排序的方括号符号 
\metacharacter      转义的元字符 
[ ]                 方括号表达式 
\( \) \digit        子表达式与后向引用 
* \{ \}             重复前置的单个字符 
无符号               连续的字符 
^ $ 锚点

ERE优先级(由高至低)

运算符              含义 
[..] [==] [::]     用于字符排序的方括号符号 
\metacharacter     转义的元字符 
[ ]                方括号表达式 
( )                分组 
* + ? {}           重复前置的正则表达式 
无符号              连续的字符 
^ $ 锚点
|                  交替

BRE 与 ERE 的区别

BREERE在大多数的元字符与功能应用上几乎是完全一致的,但是ERE里有些元字符看起来与BRE类似,却具有完全不同的意义。

匹配单个字符

ERE与BRE基本一致,比如一般字符,用于转义的反斜杠,以及方括号表达式。

ERE中不存在后向引用

圆括号在ERE中表示分组,而\( \)在ERE中表示匹配左括号与右括号。

BRE中没有交替与分组

  • ERE拥有交替字符|,用于匹配多个字符序列,比如 one|two|three|four
  • ERE拥有分组(),用于表达式群,比如(one)+用于匹配一个或多个连续的one
  • ERE可以组合使用,如this is (one|two)或者 this is (one|two)*匹配0个或多个one或者two

停驻文本匹配(锚点)

^$ 在BRE与ERE表示的意义是相同的,需要注意的是它们在方括号表达式中将会失去它们的特殊意义 组合使用,如this is ^(one|two)$匹配one或者two

GNU表达式运算符

运算符           含义 
\w            匹配任何单词 
\W            匹配任何非单词 
\< \>         匹配单词的起始或结尾 
\b            匹配单词的起始或结尾处,所找到的空字符串



回到页面顶部