Ruby 基础教程第4版读书笔记 4 - 正则表达式类

关于正则表达式

正则表达式对象的创建方法

  • 通过 // 将表示正则表达式模式的字符串括起来
  • Regexp.new(str) 创建对象
  • 也可以通过 %r 的特殊语法来创建
/R..Y/

re = Regexp.new("Ruby")

%r(模式)
%r<模式>
%r|模式|
%r!模式!

正则表达式的模式与匹配

  • =~ 方法是正则表达式中常用的方法,可以判断正则表达式是否与指定的字符串匹配
  • 无法匹配时返回 nil

匹配字符

  • /ABC/ 匹配普通字符 ABC
  • ^ 匹配行首, $ 匹配行尾
  • \A 匹配字符串开头, \z, \Z 匹配字符串末尾。很少用
  • [AB] 匹配 A 或者 B
  • [A-Za-z0-9_-] 匹配全部英文和数字以及,_ 和 -,如果 - 表示的是单纯的字符 -,就必须放在开头或者末尾
  • [^A] 匹配除 A 之外的
  • . 匹配任意字符
  • \s 匹配空格,制表符,换行符,换页符
  • \d 匹配数字
  • \w 匹配英文字母和数字
  • \ 元字符转义
  • | 在几个候补模式中匹配任意一个
/\AAB/ =~ "ABC" #=> 0
/BC\z/ =~ "ABC" #=> 1
/(ABC|DEF)$/ =~ "ABC" #=> 0

重复

  • * 重复0次以上
  • + 重复1次以上
  • ? 重复0或1次
  • () 重复匹配多个字符
/el*/ =~ "Hello" #=> 1
/^(ABC)*$/ =~ "ABCABC"

贪婪匹配和懒惰匹配

  • 匹配 0 次以上的 * 以及匹配 1 次以上的 + 会匹配尽可能多的字符,称为贪婪匹配
  • 匹配尽可能少的字符串成为懒惰匹配
  • *? 0 次以上的重复中最短的部分
  • +? 1 次以上的重复中最短的部分

正则表达式的选项

设定正则表达式时,只需要 /.../ 后面指定即可,比如 /.../im。 Regexp.new 方法中的第 2 个参数可用于指定选项常量。可以用 | 来指定多个选项

  • i 忽略英文字母的大小写 Regexp::IGNORECASE
  • x 忽略正则表达式中的空白字符以及 # 后面的字符,可以用来写注释 Regexp::EXTENDED
  • m 指定这个选项后,可以使用 . 匹配换行符 Regexp::MULTILINE
str = "ABC\nDEF\nGHI"
p /DEF.GHI/ =~ str #=> nil
p /DEF.GHI/m =~ str #=> 4
Regexp.new("Ruby", Regexp::IGNORECASE | Regexp::MULTILINE)

捕获

  • 从正则表达式的匹配部分提取其中的某部分。通过 $数字 这种形式的变量,就可以获取匹配了正则表达式中用 () 扩住的部分的字符串。
  • 我们可以使用 (?:) 过滤不需要捕获的模式。
/(.)(.)(.)/ =~ "abc"
first = $1
second = $2
third = $3
p first #=> "a"
/(.)(\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"

使用正则表达式

  • sub 方法只置换首次匹配的部分,gsub 方法则会置换所有匹配的部分。
  • 这两个方法还可以使用代码块,程序会将字符串中匹配的部分传递给块,并在块中使用该字符串进行处理。块中返回的字符串会置换字符串中匹配的部分。
str = "abracatabra"
nstr = str.sub(/.a/) do |matched|
  '<' + matched.upcase + '>'
end
p nstr #=> 'ab<RA>catabra'
  • scan 方法不能做置换操作。在正则表达式中时候 () 时,匹配部分会以数组的形式返回。
  • 如果指定与 () 相等数量的块参数,则返回的结果就不是数组,而是各个元素。
  • 如果没有指定块,则直接返回匹配的字符串数组。
"abracatabra".scan('(.)(a)') do |matched|
  p matched
end

#=>
["r", "a"]
["c", "a"]
["t", "a"]
["r", "a"]
"abracatabra".scan('(.)(a)') do |a, b|
  p a + "-" + b
end

#=>
"r-a"
"c-a"
"t-a"
"r-a"
"abracatabra".scan('(.)(a)') #=> ["ra", "ca", "ta", "ra"]

如果觉得我的文章对您有用,请在支付宝公益平台找个项目捐点钱。 @Victor Nov 27, 2014

奉献爱心