您的位置:首页 > 其它

正则表达式

2014-11-16 00:00 411 查看

1. 综述

正则表达式(regular expression)通常简写为 regex 或 re,是一种指定字符串模式的简洁方式。

图 20-1、20-2、20-3汇总了正则表达式的使用语法。



正则表达式是一种指定字符模式的简洁方式。在正则表达式中,普通字符匹配自身,特定的元字符拥有特殊的含义。本表列举了用来执行基本模式匹配的元字符。



在正则表达式中,下述元字符称为重复运算符,可以用来匹配多个指定字符的实例。

注意:一些程序不支持{,m},因为{,m}不是标准的。



正则表达式中可以包含有定义一组字符的字符类。为了方便起见,正则表达式中有一组预定义字符类,可以将这些预定义字符类用作字符集合的缩写。本表示范了最重要的预定义字符类。注意方括号和冒号都是名称的一部分。

最右边的一列给出了与预定义字符类等价的字符范围。如果系统使用的是 C 排序序列,则可以使用这些范围取代类的名称。为了确保系统使用的是 C 排序序列,可以将环境变量 LC_COLLATE 的值设置为 C。

2. 基本和扩展正则表达式

Unix支持两种主要的正则表达式变体:一个现代版本,一个以前的废弃版本。现代版本的正则表达式是扩展正则表达式(extended regular expression),或者简称为 ERE。它是当前的标准,疏于 IEEE 1003.2 标准(POSIX 的一部分)。

以前版本的正则表达式是基本正则表达式(basic regular expression),或者简称为 BRE。因其功能弱,语法容易混淆,已废弃。但仍然有时候不得不选择使用基本正则表达式。(例如,sed 只支持 BRE)

使用扩展正则表达式:grep -E 或 egrep

图 20-4,列举了基本正则表达式的限制,供参考



3. 匹配单词和行

假定有一个文件 data,考虑以下用法:

grep '^Harley' data

grep 'Harley$' data

grep '^Harley$' data

grep '^$' data | wc -l

grep '\<kn' data

grep 'ow\>' data

grep '\<know\>' data

下述3条命令都是等价的:

grep -w 'cat' data

grep '\<cat\>' data

grep '\bcat\b' data

4. 匹配字符:字符类

假定有一个文件 data,考虑以下用法:

grep 'Har..y' data

grep 'H[aA]' data

grep 'li[cs]en[cs]e' data

grep '\<li[cs]en[cs]e\>' data

5. 预定义字符类:范围

有一些字符集是比较常见的,因此他们被冠以相应的名称,从而方便使用。这些字符集称为预定义字符类

预定义字符类的使用比较直接,除了一个规则之外,这个规则是:方括号实际上是名称的一部分。因为,当时用预定义字符类时,必须包含第二组方括号,以维持正确的语法(当使用字符类时,外面的方括号不属于类)。

grep '21[[:alpha:]]' data

grep '[[:upper:]][[:upper:]][[:digit:]][[:lower:]]' data

grep '[3-7]' data

grep 'X[0-9][0-9]' data grep 'X[[:digit:]][[:digit:]]' data

grep 'X[^ao]' data

grep '[^A-Za-z]' data

grep '[^[:alpha:]]' data

6. 区域设置和排序序列

此处不单独阐述。为了将字典排序序列改变成 C 排序序列,提示以下命令:

export LC_COLLATE=C

export LC_COLLATE=POSIX

setenv LC_COLLATE C

setenv LC_COLLATE POSIX

locale

locale -a

7. 使用范围和预定义字符类

考虑以下命令:

grep 'H[[:lower:]]' data

grep 'H[a-z]' data

grep '[A-Za-z][0-9][a-z]' data

grep '[[:alpha:]][[:digit:]][[:lower:]]' data

grep '[A-Z][0-9][A-Z] [0-9][A-Z][0-9]'

data grep '[[:upper:]][[:digit:]][[:upper:]] [[:digit:]][[: upper:]][[:digit:]]' data

选择使用哪一种类型的字符类——是范围还是预定义名称——由自己决定。许多以前的 Unix 用户倾向于使用范围,因为他们学习得就是范围。此外,范围还比名称更容易键入。

但是,名称更可读,从而使得它们更适合在 shell 脚本中使用。另外,不管使用哪一种区域设置或语言,名称总是正确的,因此它们的移植性更出色。例如,假设处理的文本中包含非英语字符,如 é(有重音符的 e)。通过使用 [:lower:],就可以确保获取 é。但是,如果使用a-z的话,可能实现不了这种效果。

8. 重复运算符

考虑以下命令:

grep 'H[a-z]*' data

grep 'H[[:lower:]]*' data

grep 'error.*code' data

grep ':.*:' data

grep 'variable[0-9]+' data

grep 'variable[[:digit:]]+' data

grep '[vV]ariable[0-9]+' data

grep 'colou?r' data

grep '\<[0-9]{2,3}\>' data

grep 'cat|dog|bird|hamster' data

grep '\<(cat|dog|bird|hamster)\>' data

grep '\$' data

grep '\\\*.*[A-Za-z]+\$' data

10. 解决3个有趣的难题

字典文件常见位置:

/usr/share/dict/words

/usr/dict/words

/usr/share/lib/dict/words

1. 哪些英语单词以“qu”开头并以“y”结尾?

grep '^qu[a-z]+y$' /usr/share/dict/words

2. 查找一个包含所有 5 个元音字母 a、e、i、o、u(并且以该顺序出现)的普通英语单词。这 5 个字母不必连在一起,但是它们必须按字母表顺序出现。

grep 'a[a-z]*e[a-z]*i[a-z]*o[a-z]*u' /usr/share/dict/words

3. 查找所有两个字母长的 Unix 命令

ls /bin | grep '^[a-z]{2}$'

ls /bin | egrep '^[a-z]{2}$'

ls /bin | grep '^[a-z][a-z]$'

ls /usr/bin | grep '^[a-z]{2}$'

ls /bin | grep -c '^[a-z]{2}$'

ls /usr/bin | grep -c '^[a-z]{2}$'

附录1. 通配符

每当键入以文件名作为参数的命令时,可以通过使用特定的元字符——通配符(wildcard)——指定多个文件名。元字符是由shell 解释时拥有特殊含义的字符。当在文件名中使用通配符时,通配符就拥有特殊的含义。

乍一看,通配符和正则表达式元字符及其相似。实际上,通配符更加简单一些。此外,它们只有一个用途:当键入一条命令时匹配一组文件名。

图 24-5 列出了基本的通配符及其含义。注意:当键入路径名时,不能匹配 / 字符,该字符必须显示键入。



根据所使用的 shell 的类型不同,使用通配符指定文件的正式称呼也有所不同。在 Bash 中,称之为路径名扩展(pathname expansion);在 Korn shell 中,称之为文件名生成(filename generation);在 C-Shell 或 Tcsh 中,称之为文件名替换(filename substitution)。当 shell 执行实际替换时,称之为通配(globbing)

通配符可以使用范围匹配指定字符集中的字符。最常见的包括 [a-z] 匹配小写字母,[A-Z] 匹配大写字母。这类范围适用于 C 区域设置,而不适用于 en-US 区域设置。作为备选方法,可以使用预定义字符类替代范围。图 24-6 中列举了一些最重要的预定义字符类。



一些例子:

ls h*

ls /bin/[a-z][a-z] /usr/bin/[a-z][a-z]

ls /bin/[[:lower:]][[:lower:]] /usr/bin/[[:lower:]][[:lower:]]

ls /home/{harley,weedly,tln}

cat olddata1 olddata2 olddata3 newdata1 newdata2 newdata3 > master

cat {old,new}data{1,2,3} > master

cat {old,new}data[1-3] > master

mkdir ~/work/essays ~/work/photos ~/work/bin ~/work/music

mkdir ~/work/{essays,photos,bin,music}

touch data{old,new,backup,master,final}

正如前面所述,当 shell 匹配通配符时,在参数传递给程序之前,通配符已变成实际文件名。如果使用的模式不匹配任何文件,那么 shell 将显示一个适当的消息。

附录2. grep 重要的选项

以下是一些例子:

ls -F /etc | grep -c "/"

grep -i pizza food-costs

grep -in pizza food-costs

grep -l Harley names oldnames newnames

grep -L Harley names oldnames newnames

grep -w now memo

grep -v DONE homework

grep -cv DONE homework

grep -x Harley names

grep -r initialize admin

grep -rs / 'shutdown now'

附录3. 补充

\s:匹配任意的空白符

\S:匹配任意不是空白符的字符
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息