打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
正则表达式(Regular Expression) 简介

正则表达式(RegularExpression) 简介

l       为什么要使用正则表达式

UNIX 中提供了许多 指令 tools, 它们具有在文件中 查找(Search)字串或替换(Replace)字串 的功能. grep, vi , sed, awk,...

不论是查找字串或替换字串, 都得先告诉这些指令所要查找(被替换)的字串为何.若未能预先明确知道所要查找(被替换)的字串为何, 只知该字串存在的范围或特征时,例如 :

  ()找寻 "T0.c", "T1.c", "T2.c"...."T9.c" 当中的任一字串.

 ()找寻至少存在一个 "A"的任意字串.

这情況下,如何告知执行查找字串的指令所要查找的字串为何.

() , 要查找任一在 "T" ".c" 之间存在一个阿拉伯数字的字串;当然您可以列举的方式, 一一把所要找寻的字串告诉执行命令的指令.但例 () 中合乎该条件的字串有无限种可能, 势必无法一一列举.此时,便需要另一种字串表示的方法(协定).

l       什么是正则表达式

正则表达式(以下简称 Regexp)是一种字串表达的方式. 可用以指定具有某特征的所有字串.

: 为区別于一般字串, 本附录中代表 Regexp 的字串之前皆加 "Regexp". awk 程式中常以/..../括住 Regexp; 以区別于一般字串.

l       组成正则表达式的元素

普通字符 除了 . * [ ] + ? ( ) \  ^ $ 外之所有字符.

由普通字符所组成的Regexp其意义与原字串字面意义相同.

例如:Regexp "the" 与一般字串的 "the" 代表相同的意义.

. (Meta character) : 用以代表任意一字符.

须留心UNIX Shell 中使用"*"表示Wild card, 可用以代表任意长度的字串.Regexp 中使用"." 来代表一个任意字符.(注意: 并非任意长度的字串)Regexp "*" 另有其它涵意, 并不代表任意长度的字串.

^ 表示该字串必须出现于行首.  

$ 表示该字串必须出现于行末

例如 :

Regexp /^The/ 用以表示所有出现于行首的字串 "The".

Regexp /The$/ 用以表示所有出现于行末字串 "The".

\ 将特殊字符还原成字面意义的字符(Escape character)

Regexp 中特殊字符将被解释成特定的意义. 若要表示特殊字符的字面(literal meaning)意义时,在特殊字符之前加上"\"即可.

例如 :

使用Regexp来表示字串 "a.out", 不可写成 /a.out/.

因为"."是特殊字符,表任一字符. 可符合 Regexp / a.out/ 的字串将不只 "a.out" 一个; 字串 "a2out","a3out", "aaout" ...都符合 Regexp /a.out/  正确的用法为:  / a\.out/

[...]字符集合, 用以表示两中括号间所有的字符当中的任一个.

例如:

Regexp /[Tt]/ 可用以表示字符 "T" "t". Regexp /[Tt]he/ 表示 字串 "The" "the".

字符集合[...] 內不可随意留空白.

例如:Regexp /[ Tt ]/ 其中括号內有空白字符, 除表示"T","t" 中任一个字符, 也可代表一个" "(空白字符)

- 字符集合中可使用 "-" 来指定字符的区间, 其用法如下:

Regexp /[0-9]/ 等于 /[0123456789]/ 用以表示任意一个阿拉伯数字.

同理Regexp /[A-Z]/ 用以表示任意一个大写英文字母.

但应留心:

Regexp /[0-9a-z]/ 并不等于 /[0-9][a-z]/; 前者表示一个字符,后者表示二个字符.

Regexp /[-9]/ /[9-]/ 只代表字符 "9" "-".

[^...]使用[^..] 产生字符集合的补集(complement set).

其用法如下:

例如: 要指定 "T" "t" 之外的任一个字符, 可用 /[^Tt]/ 表之.

同理Regexp /[^a-zA-Z]/ 表示英文字母之外的任一个字符.

须留心"^" 的位置 :"^"必须紧接於"["之后, 才代表字符集合的补集

例如 :Regexp/[0-9\^]/ 只是用以表示一个阿拉伯数字或字符"^".

* 形容字符重复次数的特殊字符.

"*" 形容它前方之字符可出现 1 次或多次, 或不出现(0).

例如:

Regexp /T[0-9]*\.c/ * 形容其前 [0-9] (一个阿拉伯数字)出现的次数可为 0次或 多次.Regexp/T[0-9]*\.c/ 可用以表示"T.c","T0.c", "T1.c"..."T19.c"

+形容其前的字符出现一次或一次以上.

例如:

Regexp /[0-9]+/ 用以表示一位或一位以上的数字.

  形容其前的字符可出现一次或不出现.

例如:

Regexp /[+-]?[0-9]+/ 表示数字(一位以上)之前可出现正负号或不出现正负号.

(...)用以括住一群字符,且将之视成一个group(见下面说明)

例如 :

Regexp /12+/   表示字串 "12","122", "1222", "12222",...

Regexp /(12)+/ 表示字串 "12","1212", "121212", "12121212"....

上式中12 ( )括住, "+" 所形容的是 12, 重复出现的也是 12.

| 表示逻辑上的""(or)

例如:

Regexp / Oranges? | apples?  |water/ 可用以表示字串"Orange", "Oranges" "apple", "apples"  "water"

l       match是什么 

讨论Regexp , 经常遇到 "某字串匹配( match ) Regexp"的字眼. 其意思为 :  "这个 Regexp 可被解释成该字串".

[ 例如] :

字串"the" 匹配(match)Regexp /[Tt]he/.

因为Regexp /[Tt]he/ 可解释成字串 "the" "The", 故字串 "the" "The"都匹配(match) Regexp /[Th]he/.

l       awk 中提供二个关系运算符(Relational Operator,见注一) ~   !~,

它们也称之为 match, not match.但函义与一般常称的 match 略有不同.

其定义如下:

表一字串, B 表一 Regular Expression

只要 A 字串中存在有子字串可 match( 一般定义的 match) Regexp  B , A ~B 就算成立, 其值为 true, 反之则为 false.

! ~ 的定义与~恰好相反.

:

"another" 中含有子字串 "the" match Regexp /[Tt]he/ , 所以

"another" ~ /[Tt]he/  之值为 true.

[] : 有些论著不把这两个运算符( ~, !~) Relational Operators 归为一类.

l       应用 RegularExpression 解题的简例

下面列出一些应用 Regular Expression 的简例, 部分范例中会更改$0 之值, 若您使用的 awk不允许用户更改 $0, 请改用 gawk.  

1:

将文件中所有的字串 "Regular Expression" "Regular expression" 换成 "Regexp"

awk '

{ gsub( /Regular[ \t]+[Ee]xpression/,"Regexp")

print

}

' $*

2:

去除文件中的空白行(或仅含空白字符或tab的行)

awk '$0 !~ /^[ \t]*$/ { print }' $*

3:

在文件中具有 ddd-dddd (电话号码型态, d digital)的字串前加上"TEL : "

awk '

{ gsub( /[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/,"TEL : &" )

print

}

' $*

4:

从文件的Fullname 中分离出 路径 档名

awk '

BEGIN{

Fullname = "/usr/local/bin/xdvi"

match( Fullname, /.*\//)

path = substr(Fullname, 1, RLENGTH-1)

name = substr(Fullname, RLENGTH+1)

print "path :", path,"  name:",name

}

' $*

结果印出

path : /usr/local/bin   name : xdvi

5:

将某一数值改以现金表示法表示(整数部分每三位加一撇,且含二位小数)

awk '

BEGIN {

Number = 123456789

Number = sprintf("$%.2f",Number)

while( match(Number,/[0-9][0-9][0-9][0-9]/ ) )

    sub(/[0-9][0-9][0-9][.,]/,",&", Number)

print Number

}

' $*

结果输出

$123,456,789.00

6:

把文件中所有具 "program数字.f"形态的字串改为"[Ref : program数字.c]"

awk '

{

while( match( $0, /program[0-9]+\.f/ )  ){

    Replace = "[Ref : "substr( $0, RSTART, RLENGTH-2) ".c]"

    sub( /program[0-9]+\.f/,Replace)

}

print

}

' $*

----------------


正则表达式的介绍:

1.可以使用字符作为一个通配符来代替除换行符(\n)之外的任意一个字符,例如: .at可以与"cat","sat","mat"等匹配.通常,这种通配符用于操作系统中文件名匹配.

2.[a-z],任何含在[]中的内容都是一个字符,只匹配一个字符.

如:[a-zA-Z]代表任意大小写字母.

3.[^a-z].匹配任何不属于a-z中的字符.

4.[a-z&&[hij]].匹配hij任何一个(交集)

5.\s.匹配空字符(空格,tab,\n,换页,回车)

6.\S.匹配非空字符(和[^\s]一样)

7.\d.匹配数字,相当于[0-9]

8.\D.匹配非数字,相当于[^0-9],匹配中文,空格,换行符

9.\w.匹配词字符,相当于[a-zA-Z0-9],不包含中文,不能代表空格,换行符

10.\W.匹配非词字符,相当于[^\w],匹配一个中文字

逻辑运算符:

|:管道符.如:x|y表示x或y

():捕获组.(abc)|(xyz)表示abc或xyz

边界匹配符:

^:从头匹配

$:从尾匹配

\b:词界.

\B.非词界

量词:

量词描述一个模式吸收输入文本的方式.

*:前面字符或组匹配0或多个

+:前面字符或组匹配1或多个

:前面字符或组匹配0或1个

{n}:前面字符或组的数量为n个

{n,}:前面字符或组的数量至少n个

{n,m}:前面字符或组数量至少n个,最多m个

^表示字符串必须以后面的规则开头, 在这里就是说字符串必须以\s*开头.

\s 是空格的意思, * 表示有0个或多个

\s* 就是有0个或多个空格

(^\s*) 表示的就是以0个空格或者多个空格开头

| 表示或的意思, 也就是满足| 左边的也成立, 满足 | 右面的也成立.

\s*前面说过了

$ 的意思是字符串必须以前面的规则结尾

(\s*$) 的意思就是, 以0个空格或者多个空格结尾

/.../g 是正则表达式的属性, 表示全文匹配, 而不是找到一个就停止.

所以这个正则表达式替换的就是前导空格和后导空格
因为有前导空格, 就说明以0个或多个空格开头, 满足正则表达式中 | 前面的条件: (^\s*)
而如果有后导空格, 就说明以0个或多个空格结尾, 满足正则表达式中 | 后面的条件: (\s*$)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
35个参数13个案例,全面解析Linux三剑客之grep命令
正则表达式的基础语法
QGIS字段计算器常用函数详解
Javascript正则表达式详解
正则表达式及常用用法
正则表达式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服