前言
Ruby
对正则表达式支持比较好,简单整理一下。开门推荐三链接。 Rubular:在线 Ruby 正则表达式精品编辑器,支持多版本 Ruby Ruby Doc Ruby (英文)文档 30 分钟入门正则表达式: 还不错的正则整理文档
CheatSheet
语法
Ruby 中正则组成比较简单,模式如下,表达式返回 RegExp
对象。
/pattern/optional_modifier
复制代码
万物皆对象,可以验证下
?> puts /GracKanil/.class
Regexp
=> nil
复制代码
既然是对象,可以创建 RegExp 对象,用于正则匹配
?> r = Regexp.new 'Grac'
=> /Grac/
>> p "Grac Kanil".match r
#<MatchData "Grac">
=> #<MatchData "Grac">
复制代码
一般规则
- 匹配字符
/G/
复制代码
- 匹配特殊符号,包括
^
,$
,?
,.
,/
,\
,[
,]
,{
,}
,(
,)
,+
,*
/\?/
复制代码
.
匹配任意字符
/.G/ # 匹配 KG, kG ...
复制代码
- 匹配范围
/[ab]c/ # 匹配 ac 或者 bc
/[a-z]/
/[a-z0-9A-Z]/
复制代码
- 匹配不在该范围的字符串
/[^a-z]/ # 不含小写字母的字符串
复制代码
- 任意数字,字母,空白符
/[\d]/ # 任意数字
/[\w]/ # 任意字母
/[\s]/ # 任意空字符,空格、TAB、换行
/[\D]/,/[\W]/,/[\S]/ 均为上述相反情况
复制代码
高级规则
- 重复
? 重复零次或一次
* 重复零次或更多次
+ 重复一次或更多次
{n} 重复n次 # /d{3}/ 匹配 3 个数字
{n,} 重复n次或更多次 # /d{3,}/ 匹配 3 个数字以上
{n,m} 重复n到m次 # /d{1,10}/ 匹配 1-10 个数字
复制代码
匹配操作符
检查字符串中是否包含可以匹配的正则表达式,如果有,返回第一个匹配的字符的索引位置,如果没有,返回 `nil`。
>> "Grac Kanil" =~ /an/
=> 6
>> "Grac Kanil" =~ /at/
=> nil
>> "Grac Kanil" =~ /an/ ? "yes" : "no"
=> "yes"
大小写字母和数字范围模式匹配
?> "Grac Kanil" =~ /[aeiou]/ ? "yes" : "no"
=> "yes"
>> "Grac Kanil" =~ /[mpt]/ ? "yes" : "no"
=> "no"
`[]`表示同时搜索的单个字符列表
?> "Grac Kanil" =~ /[a-z]/ ? "yes" : "no"
=> "yes"
>> "Grac Kanil" =~ /[0-9]/ ? "yes" : "no"
=> "no"
>> "Grac Kanil" =~ /[A-Z]/ ? "yes" : "no"
=> "yes"
复制代码
regexp#match(str) 匹配
返回 MatchData
,一个数组,从 0 开始,还有 match.pre_match
返回匹配前内容,match.post_match
返回匹配后内容
?> c = /cat/.match("bigcatcomes") # 等价于 c = /cat/.match %r{bigcatcomes}
=> #<MatchData "cat">
>> c.pre_match
=> "big"
>> c.post_match
=> "comes"
>> c[0]
=> "cat"
复制代码
与此同时,可以使用 str.match regex
>> "Grac Kanil".match /.rac/
=> #<MatchData "Grac">
复制代码
匹配所有
regexp#match()
只能匹配一次,如果想匹配所有要用 regexp#scan()
?> "abcabcabz".scan(%r{abc}).each {|item| puts item}
abc
abc
=> ["abc", "abc"]
复制代码
分组匹配
Ruby 分组匹配和其他语言分组匹配相似,需要分组的部分加上括号
特殊变量
& ,$' 这三个变量分别表示【上次匹配之前的字符串 等同于 pre_match】、【匹配的字符串】、【上次匹配结果之后的字符串 等同于 post_match】
>> puts "Grac Kanil is a name." =~ /Kanil/
5
=> nil
>> p $`
"Grac "
=> "Grac "
>> p $&
"Kanil"
=> "Kanil"
>> p $'
" is a name."
=> " is a name."
复制代码
替换
很多时候需要替换字符串中所有的子串,Ruby 使用 sub()
和 gsub()
可以简单实现。
sub
只替换第一次匹配gsub(g:global)
会替换所有的匹配,- 没有匹配到返回原字符串的
copy
字符串
str = "ABDADA"
new_str = str.sub(/A/, "*") #返回"*BDADA"
new_str2 = str.gsub(/A/, "*") #返回"*BD*D*"
复制代码
修饰语
也正是 /pattern/optional_modifier
中的 optional_modifier
- i 忽略大小写,/abc/i 可以匹配 ABC,abc,Abc 等。
- m 使得正则表达式可以和任何字符匹配,包括换行符,通常情况下圆点通配符不匹配换行符。
- x 忽略空格,允许在整个表达式中放入空白符和注释。 ...
锚
^
字符匹配了字符串或行的开头
/^me/ # 匹配以 me 开头的字符串
复制代码
$
字符匹配了字符串或行的结尾
/me$/ # 匹配以 me 结尾的字符串
复制代码
\A
字符匹配了字符串的开头
/\ARuby/ # 匹配以 "Ruby" 开头的字符串
复制代码
\Z
字符匹配了字符串的结尾
/Ruby\Z/ # 匹配以 "Ruby" 结尾的字符串
复制代码
\b
字符匹配词的边界
/\bRuby\b/ # 匹配单词边界的 "Ruby"
复制代码
\B
字符匹配非词的边界
/\brub\B/ # 匹配 "rube" 和 "ruby" 中的 "rub",但不匹配单独的 "rub"
复制代码
贪婪匹配和不贪婪匹配
/<.*>/ # 贪婪重复:匹配 "<ruby>perl>"
/<.*?>/ # 非贪婪重复:匹配 "<ruby>perl>" 中的 "<ruby>"
复制代码