7.1 正则可做啥
- 测试串是否匹配指定的模式
- 从串中提取内容它们要么全部匹配要么部分匹配指定的模式
- 替换串中的内容根据指定的模式
7.2 Ruby的正则
正则式的写法:/模式/。除了.|()[]{}+\^$*?,其它串都标识要匹配自身,如果希望匹配这些特殊字符,则使用\作前缀,如/\*/,表示匹配一个*,同样 /\//表示匹配/。
模式串相当于用双引号括起来的串,里面可以使用#{...}表达式来动态设值。
Matching Strings with Patterns
~=用于匹配指定的模式,返回的是第一个匹配的位置,从0开始。
/cat/ =~ "dog and cat" # => 8
/cat/ =~ "catch" # => 0
/cat/ =~ "Cat" # => nil
#也可以颠倒一下位置
"dog and cat" =~ /cat/ #=>
不匹配返回nil,同样可作为if while的条件
str = "cat and dog"
if str =~ /cat/
puts "There's a cat here somewhere"
end
假设有这样的文本文件
0: This is line one
1: This is line two
2: This is line three
3: And so on...
File.foreach("testfile").with_index do |line, index|
puts "#{index}: #{line}" if line=~ /on/
end
produces:
0: This is line one
3: And so on...
#如果希望不匹配,使用!~与=~对应
if line !~ /on/
将打印:
produces:
1: This is line two
2: This is line three
Change Strings with Patterns
str = "Dog and Cat"
new_str = str.sub(/Cat/, "Gerbil")
#sub只会替换第一个匹配串,gsub会替换全部,g表示global。
sub是gsub都返回替换后的新串,如果没有替换发生,则返回是原串的copy。
如果希望在原串上直接修改,使用sub!与gsub!。但是要注意:sub!与gsub!在没有匹配出现时,返回nil。
7.3 Digging Deeper(百尺杆头-更进一步)
正则式在Ruby对应的类是Regexp,可将其对象分配给变量,传入方法。
str = "dog and cat"
pattern = /nd/
pattern =~ str #=> 5
str =~ pattern #=>5
创建正则式除了/.../以外,还可以直接调用Regexp#new,或者%r{...}
/mm\/dd/与Regexp.new("mm/dd")与%r{mm/dd}产生的Regexp对象是一样的。
正则式可选项
创建正则式时,可添加可选择项。或选择的添加位置如下XX位置。/.../xx或Regexp.new("", xx)
i 表示忽略大小写
o 只替换一次,模式中包含#{...}的情况下,只替换一次。
m "."默认表示除换行外的任意字符,添加/m后,表示所有字符;
x 支持正规式的格式化
Matching Against Patterns(匹配对应的模式)
定义了Regexp对象后,就可以通过Regexp#match(string)或=~或!~来匹配模式了,
name = "Fats Waller"
name =~ /a/ # => 1
name =~ /z/ # => nil
/a/ =~ name # => 1
/a/.match(name) # => #<MatchData "a"> 这里返回的是对象
Regexp.new("all").match(name) # => #<MatchData "all">
#两种格式在没有匹配上时,都返回ni
使用MatchData对象,能更易操作匹配返回的结果。
#match#pre_match 匹配前的串
#match[0]匹配的第一个位置
#match#post_match匹配后的串
def show_regexp(string, pattern)
match = pattern.match(string)
if match
puts "#{match.pre_match}->#{match[0]}<-#{match.post_match}"
else
"no match"
end
show_regexp('very interesting', /t/) # => very in->t<-eresting
show_regexp('Fats Waller', /lle/) # => Fats Wa->lle<-r
show_regexp('Fats Waller', /z/) # => no match
Deeper Patterns
. | ( ) [ ] { } + \^ $ * ?这些是特殊字符,需要使用规避符。下面对这些特殊字符的意义进行描述。
^或$,强制只匹配start or end of line,一行的开始与结束。与之相似的是\A与\z 及\Z(如果行以\n结束,则匹配\n前面的部分)。
同样\b表示匹配独立的单词,而\B表示匹配不是独立的单词。见下面的示例:
str = "this is\nthe time"
show_regexp(str, /^the/) # => this is\n->the<- time
show_regexp(str, /is$/) # => this ->is<-\nthe time
show_regexp(str, /\Athis/) # => ->this<- is\nthe time
show_regexp(str, /\Athe/) # => no match
show_regexp("this is\nthe time", /\bis/) # => this ->is<-\nthe time
show_regexp("this is\nthe time", /\Bis/) # => th->is<- is\nthe time
Character Classes(匹配字符集合)
[...]表示匹配这其中的任意一个。
show_regexp('Price $12.', /[aeiou]/) # => Pr->i<-ce $12.
show_regexp('Price $12.', /[\s]/) # => Price-> <-$12.
show_regexp('Price $12.', /[$.]/) # => Price ->$<-12.
[c1-c2]表示从c1到c2
a = 'see [The PickAxe-page 123]'
show_regexp(a, /[A-F]/) # => see [The Pick->A<-xe-page 123]
show_regexp(a, /[A-Fa-f]/) # => s->e<-e [The PickAxe-page 123]
show_regexp(a, /[0-9]/) # => see [The PickAxe-page ->1<-23]
show_regexp(a, /[0-9][0-9]/) # => see [The PickAxe-page ->12<-3]
[^...]取非
show_regexp('Price $12.', /[^A-Z]/) # => P->r<-ice $12.
show_regexp('Price $12.', /[^\w]/) # => Price-> <-$12.
show_regexp('Price $12.', /[a-z][^a-z]/) # => Pric->e <-$12.
show_regexp('It costs $12.', /\s/) # => It-> <-costs $12.
show_regexp('It costs $12.', /\d/) # => It costs $->1<-2.
---------------------------------正则式到此,如果有时间后面再继-----------------------