第14章 正则表达式(Regexp)类
建立正则表达式对象
用“//”括住正则表达式的样式 |
用类方法建立对象 “Regexp.new(str)” |
以“%r”开头的写法。当正则表达式内部用到“/”字符的时候,改用“%r”会比较方便。如: %r(样式), %r<样式>, %r|样式|, %r!样式! |
正则表达式的样式与匹配
语法: 正则表达式 =~ 字符串 |
不成立时会返回nil,成立时会返回字符串中与样式匹配成功的起始位置。 |
简单匹配 |
正则表达式里的英文字母和数字,只会单纯地区匹配字符串里是否包含相同的文字。 |
样式:/ABC/ 匹配:”ABC”, “ABCD”, “123ABC” |
||||
匹配行首行尾 |
“^”表示“与行首匹配成功的样式”, 而“$”则表示“与行尾匹配成功的样式”。 |
样式:/^ABC$/ 匹配:”ABC” 不匹配:”ABCD”, “123ABC” |
||||
与“^”和“$”匹配的是行头和行尾,而非字符串的头和字符串的尾。字符串头的匹配字符是“\A”,字符串尾的匹配字符是“\Z”。 |
||||||
匹配字符范围 |
想在多个字符里选一的情况,可用“[]”括起来 ([]里没有顺序性)
|
样式:/[ABC]/, /[CBA]/ 匹配: A或B或C 样式:/[A-Za-z]/ 匹配:所有英文字母 样式:/[A-Za-z_-]/ 匹配:所有英文字母与“_”和“-” 样式:/[^ABC]/ 匹配:A、B、C以外的字符 |
||||
匹配任意字符 |
用“.”表示,可用于:
|
样式:/A.C/ 匹配:”ABC”, “12A3C45” 不匹配:”AC”, “abc” |
||||
转义字符 |
||||||
\s |
表示空白,会与空白字符(0x20)、定位字符、换行字符、换页字符匹配成功。 |
|||||
\d |
与0~9之间的数字匹配成功 |
|||||
\w |
与英文字母及数字匹配成功 |
|||||
\A |
与字符串前端匹配成功 |
样式:/\AABC/ 匹配:”ABC”, “ABCDE” 不匹配:/012ABC/ |
||||
\Z |
与字符串末端匹配成功 |
|||||
在“\”后接上“^”、“$”、“[”这些字母、数字以外的转义字符时,这些字符就不再具备转义字符的效用了,而可以去匹配这些字符本身。 |
样式:/\^ABC/ 不匹配:”ABC“ |
|||||
重复出现匹配 |
“*”:出现0次及以上 “+”:出现1次及以上 “?”:出现0次或1次 |
|||||
最短匹配 用来匹配反复0次及以上的“*”与反复1次及以上的“+”,会尽可能匹配出最长的结果。如果只想比较出符合样式最短的部分(即反复后面的样式第一次出现的位置),则可用转义字符 |
“*?”: 出现0次及以上,但取最短的结果 “+?”: 出现1次及以上,但取最短的结果 |
|||||
匹配多个字符构成的字符串 |
用“()” |
|
||||
选择匹配 |
用“|” |
样式:/^(AB|CD)+$/ 匹配:”ABCD” 不匹配:”ABCABCAB” |
||||
在建立正则表达式时,想要忽略所有转义字符,可使用quote方法。 |
re1 = Regexp.new(“abc*def”) re2 = Regexp.new(Regexp.quote(“abc*def”)) p (re1 =~ “abc*def”) #=> nil p (re2 =~ “abc*def”) #=> 0 |
|||||
正则表达式的选项
选项字符 |
选项常数 |
意义 |
s |
|
视为Shift_JIS匹配 |
e |
|
视为EUC-JP匹配 |
u |
|
视为UTF-8匹配 |
n |
|
视为单字节文字匹配 |
i |
IGNORECASE |
匹配时忽略大小写 |
x |
|
匹配时忽略样式里的空白 |
m |
MULTILINE |
多行匹配 |
o |
EXTENED |
样式内嵌表达式只做一次 |
使用Regexp.new方法建立对象时,选项常数可以传入第2个实参,而选项字符串则可以传入第3个实参。当第2个实参想指定不只一个选项时,可以使用“|”。
Regexp.new(“Ruby语言”, Regexp.IGNORECASE | Regexp.MULTILINE, “s”) |
回溯参照
正则表达式的功能并不是只用来检查是否匹配成功。还有另外一个作用是回溯参照。所谓回溯参照,是取出字符串中匹配成功部分的一部分的功能。与正则表达式中“()”所括住的部分匹配成功的字符串,可以通过$1、$2这些形如“$数字”的变量取出。
/(.)(\d\d)+(.)/ =~ “123456” p $1 #=> “1” p $2 #=> “45” p $3 #=> “6” /(.)(?:\d\d)+(.)/ =~ “123456” p $1 #=> “1” p $2 #=> “6” |
“()”同时也兼具并列多个样式在一起的功能。为防止混淆,若只要求并列样式,而不需要使用回溯参照的时候,可以写成“(?:)”。 |
/C./ =~ “ABCDEF” p $` #=> “AB” p $& #=> “CD” p $’ #=> “EF” |
除了“$数字”外,还有“$`”、“$&”、“$’”这3个变量也会储存匹配的结果。这3个变量的内容分别是“匹配成功部分左边的字符串”、“匹配成功部分的整个字符串”、“匹配成功部分右边的字符串”。 |
sub方法与gsub方法
sub与gsub方法都需要两个实参,第1个实参要指定想要匹配的正则表达式样式,而第2个实参则传入想要取代匹配成功出的字符串。sub方法只会取代第一个匹配成功处的字符串,而gsub方法则会取代所有匹配成功处的字符串。
sub与gsub方法还有加上“!”版本的方法,使用此版本,会直接取代方法的接收者这个字符串对象的内容。
str = “abc def g hi” p str.sub(/\s+/, ‘ ‘) #=> “abc def g hi” p str.gsub(/\s+/, ‘ ’) #=> “abc def g hi” |
示例:将连续出现的空白字符取代成一个空白 |
str = “abracatabra” nstr = str.sub(/.a/) {|matched| ‘<’+matched.upcase+’>’ } p nstr #=> “ab<RA>catabra” str = “abracatabra” nstr = str.gsub(/.a/) {|matched| ‘<’+matched.upcase+’>’ } p nstr #=> “ab<RA><CA><TA>b<RA>” |
sub方法与gsub方法也可以传入区块 |
scan方法
能够匹配到字符串里所有符合样式的部分 ,但不会进行取代的操作,只会获取而已。
“abracatabra”.scan(/.a/) {|matched| p matched } |
输出: “ra” “ca” “ta” “ra” |
|
“abracatabra”.scan(/(.)(a)/) {|matched| p matched } |
输出: [“r”, “a”] [“c”, “a”] [“t”, “a”] [“r”, “a”] |
当正则表达式内使用到“()”时,则匹配成功的部分会以数组的形式传入区块。 |
“abracatabra”.scan(/(.)(a)/) {|a, b| p matched } |
输出: “r-a“ “c-a“ “t-a“ “r-a“ |
在区块里指定与“()”的数量一样多的变量时,则不会传入数组,而直接依序分别指定给每个变量。 |
p “abracatabra”.scan(/.a/) #=> [“ra”, “ca”, “ta”, “ra”] |
没有指定区块时,scan方法会返回匹配成功的字符串的数组。 |
示例
匹配URL的简单写法 |
str = http://www.ruby-lang.org/ja/ %r|http://([^/]*)/| =~ str print “server address: ” $1, “\n” 输出:server address: www.ruby-lang.org |
使用正则表达式取得服务器地址以外的部分
%r|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?| |
这是RFC2396“uniform Resource Identifiers (URL): Generic Syntax”这个URL一般写法规格文件里所提供的正则表达式。以这个样式进行匹配的话,“HTTP”之类的协议名会存放在$2,服务器地址会存放在$4、路径部分会存放在$5、查询部分会存放在$7、而区段部分会存放在$9。 |
如: http://www.example.co.jp/foo/?name=bar#baz “http”是协议名,“www.example.co.jp”是主机地址,“/foo/”是路径,“name=bar”是查询,“baz”时区段名称。 |
正则表达式圣书<Mastering Regular Expression Third Edition>(Jeffrey E.F.Friedll著)