Ruby 中的正则表达式 ( regexp )

yufei       6 年, 3 月 前       1353

在详解 Ruby 中的正则表达式之前,我们先来看一段代码,就是看看 Ruby 如何使用正则表达式来匹配一个 URL 。

2.5.1 :001 > Regexp.new(/https?:\/\/[\S]+/)
 => /https?:\/\/[\S]+/ 
2.5.1 :002 > url_matcher = _
 => /https?:\/\/[\S]+/ 
2.5.1 :003 > url_matcher.match('https://www.twle.cn/')
 => #<MatchData "https://www.twle.cn/"> 
2.5.1 :004 > 
2.5.1 :005 > 
2.5.1 :006 > 
2.5.1 :007 > # Wi love Ruby!

上面这段代码使用正则表达式来匹配一个网址。如果你用过其它语言的正则表达式,那么对 /https?:\/\/[\S]+/ 应该很熟悉了。

Ruby 中的正则表达式类

首先,Ruby 中的正则表达式也是一个对象,所有和正则表达式相关的逻辑都封装在 Regexp 类中。

同时, Ruby 还提供了三种初始化一个正则表达式实例的方法

  1. Regexp.new(/.*/).class # => Regexp
  2. /.*/.class # => Regexp
  3. %r{.*}.class # => Regexp

OK ,既然知道了如何创建正则表达式,那接下来的问题来了: 如何将此 Regexp 与一个字符串相匹配 ?

MetaData 类

Regexp 类提供了一个 Regexp#match 方法,该方法将一个字符串作为参数进行测试。

/I love Ruby/.match('I love Ruby') # => #< MatchData "I love Ruby">

Regexp#match 方法会返回一个 MetaData 类的实例。这个 MetaData 类的实例封装了所有的模式匹配的结果。

我们诚挚的邀请你访问官方的 文档 ,了解 MetaData 类能够做些什么。例如,可以使用 MatchData#to_a 方法来迭代结果。

Ruby 中和正则表达式相关的魔术变量

Ruby 提供了一组跟正则表达式相关的魔术变量,Ruby 会使用 MetaData 的新实例来给这些变量自动赋值。

下面的代码是一些魔术变量的使用示例

/(I love) (Ruby)/.match("Yes, I love Ruby. We're cool.")

# $~ returns the latest instance of MatchData
$~ # => #<MatchData "I love Ruby" 1:"I love" 2:"Ruby">

$& # => "I love Ruby"   (The matching portion of the String)
$` # => "Yes, "         (Equivalent to MatchData#pre_match method)
$' # => ". We're cool." (Equivalent to MatchData#post_match method)

$1 # => "I love"
$2 # => "Ruby"
$3 # => nil

模式匹配运算符 =~

为了简化正则表达式的使用,Ruby 提供了语法糖运算符 =~,运算符可以将正则表达式与字符串匹配,并返回匹配到的模式结果

/(devscoop)/ =~ "http://ruby.devscoop.fr" # => 12
"http://ruby.devscoop.fr" =~ /(devscoop)/ # => 12

# Note that the operator returns nil if no matching found
/lol/ =~ "It's not funny" # => nil

请注意,当 =~ 方法返回时,会自动设置所有正则表达式相关的魔法变量,因为 =~ 运算符会自动实例化正则表达式 ( Regexp ) 与字符串 ( String ) 匹配结果的的 MatchData

命名捕获 ( Name Capture )

命名捕获 功能与 =~ 运算符一起使用时,就具有强大的机制,可以使用分配给 Regexp 实例的组的名称自动将匹配组的结果分配到变量中

if /(?<newsletter>devscoop)/ =~ 'http://ruby.devscoop.fr'
  p newsletter # => "devscoop"
end

Regexp#match 方法也提供了命名捕获功能,和 =~ 主要的区别在于 match 方法不会自动创建变量。

另一方面,通过使用 MatchData#[] 方法来使用返回的 MatchData 实例的命名捕获

if projects = /(?<newsletter>devscoop)/.match('http://ruby.devscoop.fr')
  p projects['newsletter'] # => "devscoop"
end

延伸阅读

Ruby 还提供了许多与正则表达式有关的方法,比如

  1. String#scan
  2. String#gsub
  3. String#[]

但这些方法不是集成到正则表达式核心中的,而是分布在字符串中。所以,本章节,我们并未介绍它们。

如果你想要了解详情,可以点击各自的链接到官方文档中浏览。

结束语

Ruby 正则表达式的方法真的是很少很少,不过功能一点也没有减少,尤其是它的魔术变量

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.