正则表达式是一些字符按照一定规则的组合。正则表达式用来表达对字符串的过滤逻辑,已经得到大多数程序设计语言的支持。

正则表达式的应用对象是文本,我们可以进行"匹配"、"截取"等工作。

正则表达式可以用简单的方式对文本进行复杂处理,这是其灵活性的体现。另一方面,由于其逻辑性非常强,表达式内容并不直观,因此较为晦涩难懂。



一、正则表达式的创建方法

1. 使用符号/ / ,如 /pattern/ 
2. 使用Regexp类的new方法,如 Regexp.new(pattern) 
3. 使用%r模式,如 %r(pattern)  %r<pattern>  %r|pattern|  %r!pattern!


二、匹配规则

1. 匹配符号  =~  !~

nil。

2. Regexp类中的match方法

nil。



三、常用符号

1. [ ]  选择多个字符中的一个,可以在一个模式中出现多次。

2. -  在[ ]中使用,表示一定范围,若出现在开头或结尾,则表示单一字符 - 。

3. ^  在[ ]中的开头使用,表示逻辑非。

4. .  匹配任何字符,换行符除外。

5. *  匹配0次以上。

6. +  匹配1次以上。

7. ?  匹配0次或1次。

8. ^  匹配行首。

9. $  匹配行尾。



四、使用反斜杠的模式

1. \A  匹配字符串开头。

2. \z  匹配字符串结尾。

3. \Z  匹配字符串结尾,若结尾为换行符,则匹配之前字符。

4. \s  匹配空白符,如空格、制表符、换行符、换页符。

5. \S  匹配非空白符。

6. \d  匹配0到9的数字。

7. \D  匹配非数字。

8. \w  匹配英文字母与数字。

9. \W  匹配非英文字母与数字。

10. \1  匹配第1个分组子表达式。



示例:

或B或C

以外的字符

全部英文字母

任意字符1次以上

正好3个数字

个或更多英文字母或数字

个、4个或5个空白符

字符数为6的行

电子邮件主题模式



五、正则表达式的选项

选项

选项常量

意义

i

Regexp::IGNORECASE

忽略大小写

x

Regexp::EXTENDED

忽略空白符以及#后面的字符

m

Regexp::MULTILINE

匹配多行,可以使用 . 匹配换行符

o


只使用一次内嵌表达式 #{ } 



六、最短匹配

* +  会匹配尽可能多的字符,即贪婪匹配,是ruby的默认匹配方式。匹配尽可能少的字符称为懒惰匹配,ruby使用以下方法进行懒惰匹配:

*?  匹配0次以上的重复中最短的部分

+?  匹配1次以上的重复在最短的部分



七、Regexp类的quote方法

quote方法用于返回转义了元字符后的正则表达式字符串。但是不可以使用元字符的格式写元字符,因此不适用于复杂情况,建议使用转义的方式。例:

re = Regexp.new(Regexp.quote("ruby"))
p (re =~ "ruby")  #=>  0



八、捕获

捕获:也称向后引用,即从正则表达式的匹配部分中提取其中一个片段,通过"$数字"形式的变量来获取匹配了正则表达式中用( )部分的内容。例:

/(.)(\d\d)+(.)/ =~ "123456"
p $1  #=>  "1"
    p $2  #=>  "45"
p $3  #=>  "6"
    /(.)(?:\d\d)+(.)/ =~ "123456"  #(?: )用于过滤不需要捕获的模式
p $1  #=>  "1"
p $2  #=>  "6"


特殊符号:$`  $&  $'

分别表示匹配部分前的字符串、匹配部分的字符串、匹配部分后的字符串。

例:

/3./ =~ "123456"
p $`  #=>  "12"
p $&  #=>  "34"
p $'  #=>  "56"



九、置换

sub方法与gsub方法:用指定的字符置换字符串中的某个部分。

sub方法只置换首次匹配的部分,gsub方法置换所有匹配的部分。

两种方法都有对应的sub!方法和gsub!方法,直接将作为接受者的对象变换为置换后的字符串。

例:

str = "abc  def    g   h"
p str.sub(/\s+/,’ ’)  #=>  "abc def    g   h"
p str.gsub(/\s+/,’ ’)  #=>  "abc def g h"



十、搜索

scan方法:获取匹配部分的字符串。

若在正则表达式中使用( ),会以数组形式返回。若指定与( )相等数量的块参数,则返回各个元素。若没有指定块,则直接返回匹配的数组。

例:


"anatagairukara".scan(/.a/) do |m|
  p m
end

"anatagairukara".scan(/(.)(a)/) do |m|
   p m
end

"anatagairukara".scan(/(.)(a)/) do |m,n|
   p m+"-"+n
end

p "anatagairukara".scan(/.a/)


>ruby demoScan.rb
"na"
"ta"
"ga"
"ka"
"ra"
["n", "a"]
["t", "a"]
["g", "a"]
["k", "a"]
["r", "a"]
"n-a"
"t-a"
"g-a"
"k-a"
"r-a"
["na", "ta", "ga", "ka", "ra"]