`
zarknight
  • 浏览: 146469 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ruby way 第三章学习『正则表达式』

阅读更多

        正则表达式历史悠久,功能强大,现代编程语言中少不了它的影子,但功能强度不大一样。Ruby把正则表达式在自身发挥的淋漓尽致 。

        刚学习正则表达式,看起来会觉得语法比较晦涩,等上手了呢,就会明白它的精髓。在这里,也不细讲正则表达式的语法问题了,只讲它在ruby中的使用。在ruby中,一个通常的正则表达式会是例如如下样子的:

/Ruby/

/[Rr]uby/

%r{xyz$}

%|[0-9]*|

等等...

而在ruby中,正则表达式有4种修饰符:

i       忽略大小写

o     只执行一次替换操作

m    多行匹配

x      使用扩展了的正则表达式语法(可以使用正则表达式的注释之类)

 

编译正则表达式
=========================================
可以使用Regexp.compile方法(和使用Regexp.new是一样的效果)来编译正则表达式。

Regexp.compile方法的第一个参数可以是一个字符串或则是一个正则表达式
(如果是一个正则表达式,并且它后面带了选项,则编译后,选项将不会出现在新的正则表达式中。)
 p1 = Regexp.compile("^foo.*")   # 结果: /^foo.*/
 p2 = Regexp.compile(/bar$/i)    # 结果:/bar/

如果要设置第二个参数,那么它的值可以是以下几个:
 Regexp::EXTENDED
 Regexp::IGNORECASE
 Regexp::MULTILINE

例如:
 p3 = Regexp.compile(/bar/, Regexp::IGNORECASE)

你如果你想同时使用他们之中的多个,则可以这样:
 options = Regexp::MULTILINE || Regexp::IGNORECASE
 pat4 = Regexp.compile("^foo", options)


它的第三个参数,是用来设置语言编码的,可以有如下值:
"N" or "n" #表示 None
"E" or "e" #表示 EUC
"S" or "s" #表示 Shift-JIS
"U" or "u" #表示 UTF-8


也可以直接使用正则表达式字面量,不用使用Regexp.compile方法或Regexp.new方法:
p1 = /^foo.*/
p2 = /bar$/i



转义正则表达式中的特殊字符
===========================================
使用Regexp.escape方法(别名方法是Regexp.quote),可以吧正则表达式中的特殊字符统统转义:
str1 = "[*?]"
str2 = Regexp.escape(str1)    # "\[\*\?\]"


访问正则表达式匹配后的数据引用
===========================================
在正则表达式中用使用括号的部分将被作为子匹配,有几中方式可以用来获取他们的引用:
1.比较“难看”方式:
使用特殊的全局变量,如:$1,$2....
str = "a123b45c678"
if /(a\d+)(b\d+)(c\d+)/ =~ str
  puts "Matches are: '#$1', '#$2', '#$3'"      # 打印: Matches are: 'a123', 'b45', 'c768'
end

我们来看下下面这段程序:
str = "a123b45c678"
str.sub(/(a\d+)(b\d+)(c\d+)/, "1st=#$1, 2nd=#$2, 3rd=#$3")   
# 结果: "1st=, 2nd=, 3rd="

为什么会结果是空呢?其实,上面的程序等同与下面的程序:
str = "a123b45c678"
s2 = "1st=#$1, 2nd=#$2, 3rd=#$3"
reg = /(a\d+)(b\d+)(c\d+)/
str.sub(reg,s2)
# 结果: "1st=, 2nd=, 3rd="

看明白了吧。
在这种情况下,我们要使用类似:\1,\2...之类的形式来引用了。
str = "a123b45c678"
str.sub(/(a\d+)(b\d+)(c\d+)/, '1st=\1, 2nd=\2, 3rd=\3') 
#注意,要使用单引号,否则会被解释成转义字符,如果用双引号,则要把斜杠转义掉,如:\\1,\\2
# 结果:"1st=a123, 2nd=b45, 3rd=c768"

我们还可以使用Ruby的block来实现上面的功能:
str = "a123b45c678"
str.sub(/(a\d+)(b\d+)(c\d+)/)  { "1st=#$1, 2nd=#$2, 3rd=#$3" }
# 结果: "1st=a123, 2nd=b45, 3rd=c678"

如果你想在匹配的时候跳过一个组的抓取,则可以使用(?: )语法:
str = "a123b45c678"
str.sub(/(a\d+)(?:b\d+)(c\d+)/, "1st=\\1, 2nd=\\2, 3rd=\\3")
# 结果:"1st=a123, 2nd=c678, 3rd="


以上的方式看起来很方便,不过,有的人会觉得它们看起来太杂乱,不好看,所以,还有以下方式来获取子匹配的引用:
pat = /(.+[aiu])(.+[aiu])(.+[aiu])(.+[aiu])/i
refs = pat.match("Fujiyama")

refs.to_a.each do |x|
  print "#{x}\n"
end

match方法将返回一个MatchData对象。

MatchData有begin和end两个方法,用来获取匹配结果在原字符串中的起始和结束位置
str = "alpha beta gamma delta epsilon"
pat = /(b[^ ]+ )(g[^ ]+ )(d[^ ]+ )/

refs = pat.match(str)

# "beta "
p1 = refs.begin(1)         # 6
p2 = refs.end(1)           # 11

# "gamma "
p3 = refs.begin(2)         # 11
p4 = refs.end(2)           # 17

# "delta "
p5 = refs.begin(3)         # 17
p6 = refs.end(3)           # 23

# "beta gamma delta"
p7 = refs.begin(0)         # 6
p8 = refs.end(0)           # 23


和begin,end方法相似的是offset方法,它返回一个数组,包括了匹配的起始和结束位置:
range0 = refs.offset(0)    # [6,23]
range1 = refs.offset(1)    # [6,11]
range2 = refs.offset(2)    # [11,17]
range3 = refs.offset(3)    # [17,23]


还有两个方法,pre_match和post_match,用来获取当前匹配结果的前一个和后一个匹配结果:
before = refs.pre_match    # "alpha "
after  = refs.post_match   # "epsilon"



 

分享到:
评论

相关推荐

    正则表达式经典实例

    对于如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,《正则表达式经典实例》给出了涉及基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案。...

    精通正则表达式(第三版)

    专家点评:《精通正则表达式》是系统学习正则表达式的唯一最权威著作。任何时候,任何地方,只要提到正则表达式著作,人们都会提到这本书。该书质量之高,声誉之盛,使得几乎没有人企图挑战它的地位,从而在正则...

    精通正则表达式 中英文

    《精通正则表达式》是系统学习正则表达式的唯一最权威著作。任何时候,任何地方,只要提到正则表达式著作,人们都会提到这本书。该书质量之高,声誉之盛,使得几乎没有人企图挑战它的地位,从而在正则表达式图书领域...

    精通正则表达式(第三版)

    专家点评:《精通正则表达式》是系统学习正则表达式的唯一最权威著作。任何时候,任何地方,只要提到正则表达式著作,人们都会提到这本书。该书质量之高,声誉之盛,使得几乎没有人企图挑战它的地位,从而在正则...

    《正则表达式经典实例》扫描版

    即使有经验的用户也经常会遇到性能不佳、误报、漏报等让人挠头的错误,本书对于如何使用正则表达式来解决一些常见的问题给出了按部就班的解决方案,其中包括c#、Java、JavaScript、Perl、PHP、Python、Ruby和VB...

    正则表达式完整高清版

    第三部分将之前介绍的各种知识落实到6种常用语言.net、java、javascript、php、python、ruby中,不但详细介绍了语言中正则表达式的用法,更点明了版本之间的细微差异,既可以作为专门学习的教材,也可以作为有用的...

    正则表达式经典实例.pdf

    对于如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,本书给出了涉及基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案。  本书的读者对象是对...

    [精通正则表达式(第3版)]中文版.(美)Jeffrey.E.F.Friedl-part1.rar

    本书自第1版开始着力于教会读者“以正则表达式来思考”,来让读者真正“精通”正则表达式。该版对PHP的相关内容、Java1.5和Java1.6的新特性作了可观的扩充讲解。任何有机会使用正则表达式的读者都会从中获益匪浅。...

    精通正则表达式~~~

    第3章:正则表达式的特性和流派概览.... 83 在正则的世界中漫步... 85 正则表达式的起源... 85 最初印象... 91 正则表达式的注意事项和处理方式... 93 集成式处理... 94 程序式处理和面向对象式处理... 95 ...

    精通正则表达式(第3版) 英文版

    “毫不夸张地说,《精通正则表达式(第3版)》是学习该工具的不二选择,也是每个程序员必备的杰作。” ——Jason Menard, Java Ranch “所有关于正则表达式的书中,找不到比这更好的了。” ——Zak Greant, Planet ...

    ruby正则表达式

    比较齐全的正则表达式,完全可以满足你平时的各种需要

    ruby正则表达式规则

    ruby正则表达式规则 ruby中经常用到的正则表达式使用方法

    正则表达式经典实例.(美)高瓦特斯,(美)利维森.pdf

    本书讲解了基于8种常用的...对于如何使用正则表达式来解决性能不佳、误报、漏报等常见的错误以及完成一些常见的任务,本书给出了涉及基于C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等编程语言的解决方案。

    正则表达式经典实例中文版 (美)高瓦特斯

    第2章 正则表达式的基本技巧 2.1 匹配字面文本 2.2 匹配不可打印字符 2.3 匹配多个字符之 2.4 匹配任意字符 2.5 匹配文本行起始和/或文本行结尾 2.6 匹配整个单词 2.7 Unicode代码点、屙陛、区块和脚本 2.8 匹配多...

    正则表达式框架OgreKit.zip

    OgreKit 是一款为 Cocoa 开发的正则表达式框架,该框架提供了一个与 Ruby 使用的相同的正则表达式引擎与一个高层次的 GUI 查找面板。可以在这里获取源码。 OgreKit 使用 Oniguruma/Onigmo 正则表达式引擎。...

Global site tag (gtag.js) - Google Analytics