`

Ruby正则表达式操作参考

阅读更多

正则表达式

下面就来讲讲ruby支持的正则表达式符号(元字符)。

有这么个规则:

  • 不带\的数字和字母不是元字符
  • 带\的符号也不是元字符

下文中出现的“匹配多字节字符的正则表达式”是指,通过使用$KCODE 进行设定,或显式地使用汉字选项(请参考正则表达式字面值 )等方式进行的匹配多字节字符的正则表达式。

  • ^

    行首。与字符串的头部或换行符之后的位置相匹配。

  • $

    行尾。与字符串的尾部或换行符之前的位置相匹配。不包括换行符本身。

    ruby 1.8 特性 :以前,只匹配字符串尾部换行符前的位置,现在则扩大到字符串的尾部。trap::Regexp

    p "\n".gsub(/$/, "o")
    => "o\n"  (1.6)
    => "o\no" (1.8)
    
  • .

    匹配除换行符以外的任意一个字符。使用正则表达式选项 m(多行模式。请参考正则表达式字面值 ) 时,则匹配包括换行符在内的任意一个字符。在匹配多字节字符的正则表达式中,则匹配一个字(非单字节)。

    当遇到不完整的多字节字符的一部分(无法判断该字符是多字节字符?二进制?还是ASCII)时,也不会匹配。

    p /./e =~ "あ"[0,1]     # => nil
    
  • \w

    字母和数字。等同于[0-9A-Za-z]

    若为匹配多字节字符的正则表达式时,则也会匹配日语的全角字符。

  • \W

    非字母和数字。\w 以外的单个字符。

  • \s

    空字符。相当于[ \t\n\r\f]

  • \S

    非空字符。[ \t\n\r\f] 以外的单个字符。

  • \d

    数字。即[0-9]

  • \D

    非数字

  • \A

    字符串头部。与^ 不同的是,它不受有无换行符的影响 。

  • \Z

    字符串尾部。若字符串以换行符结尾,则匹配换行符前的位置。

    ruby 1.8 特性 :以前,只匹配字符串尾部换行符前的位置,现在则扩大到字符串的尾部。trap::Regexp

    p "\n".gsub(/\Z/, "o")
    => "o\n"   (1.6)
    => "o\no"  (1.8)
    
  • \z

    字符串结尾。与$以及\Z不同的是,它不受有无换行符的影响。

  • \b

    在字符范围描述符之外时表示词边界(匹配从\w到\W)。在字符范围描述符之内时表示退格符(0x08)。

  • \B

    非词边界

  • \G

    在上次成功匹配的地方(之后)进行匹配(不留余地)。只有在首次使用时才会匹配到头部(与\A相同)。

    可以用在scan gsub 中。当您想在上次匹配的地方之后再进行匹配的话,可以使用。

    举个简单(没什么用)的例子。

    # 从头取出3位数字(数字必须相连)。
    str = "123456 789"
    str.scan(/\G\d\d\d/) {|m| p m }
    
  • [ ]

    指定字符范围。请参考字符范围

  • *

    前面元素至少出现0次。尽可能匹配较长的部分。

  • *?

    负责指定数量(quantifiers)。表示前面元素至少出现0次(尽量匹配短的部分)

  • +

    负责指定数量(quantifiers)。表示前面元素至少出现1次

  • +?

    负责指定数量(quantifiers)。表示前面元素至少出现1次(尽量匹配短的部分)

  • {m}
  • {m,}
  • {m,n}

    指定元素重复出现的次数(interval quantifier)。分别表示前面元素重复出现

    • m 次
    • 至少 m 次
    • 至少 m 次,至多 n 次

    {,n}{,} 将导致匹配失败。

    str = "foofoofoo"
    p str[/(foo){1}/]   # => "foo"
    p str[/(foo){2,}/]  # => "foofoofoo"
    p str[/(foo){1,2}/] # => "foofoo"
    

    正则表达式 ? , * , + 分别等同于 {0,1} , {0,} {1,}

  • {m}?
  • {m,}?
  • {m,n}?

    指定元素重复出现的次数(interval quantifier)。分别表示前面元素重复出现

    • m 次
    • 至少 m 次
    • 至少 m 次,至多 n 次

    (尽量匹配短的部分)。

  • ?

    负责指定数量(quantifiers)。表示前面元素至多出现1次。

  • ??

    负责指定数量(quantifiers)。表示前面元素至多出现1次(尽量匹配短的部分)

  • |

    选择(alternative)。

  • ( )

    正则表达式的群组化。与括号中的正则表达式相匹配的字符串将被保存下来,供后方参考使用。

  • \1 , \2 ... \n

    后方参考(back reference)。请参考后方参考

  • (?# )

    注释。括号中的任意字符串将被忽视。

  • (?: )

    不具备后方参考功能的群组化。它不为\1,\2(或$1 ,$2 )提供服务,是一种单纯的群组功能。

    /(abc)/ =~ "abc"
    p $1
    => "abc"
    
    /(?:abc)/ =~ "abc"
    p $1
    => nil
    
  • (?= )

    先行(lookahead)。使用模式(pattern)指定位置(不留间隔)

    (?=re1)re2
    

    表示将匹配同时符合re1和re2的要求的字符串。

    re1(?=re2)
    

    という山附は、稿に re2 とマッチする矢机误が鲁く、正则表达式 re1 です。

    p /foo(?=bar)/ =~ "foobar"      # => 0
    p $&    # => "foo"   (bar の婶尸の攫鼠はない)
    
  • (?! )

    否定先行(negative lookahead)。使用否定的模式(pattern)来指定位置(不留间隔)

    (?!re1)re2
    

    该正则表达式表示,匹配re1但不匹配re2。

    # 除000以外的3位数字
    re = /(?!000)\d\d\d/
    p re =~ "000"   # => nil
    p re =~ "012"   # => 0
    p re =~ "123"   # => 0
    
    # C语言标识符 (首位是[A-Za-z_]然后是[0-9A-Za-z_]的字符串)
    /\b(?![0-9])\w+\b/
    
  • (?> )

    禁用回缩功能

    该功能尚处于试验阶段。将来有可能被停用,请您注意使用。特别是不要在广义库中使用。

  • (?ixm-ixm)

    正则表达式中的i选项、x选项、m选项的开关。请您参考正则表达式字面值 来了解选项的详细内容。

    re = /A(?i)a(?-i)A/
    p re =~ "AaA"         # => 0
    p re =~ "AAA"         # => 0
    p re =~ "AAa"         # => nil
    
  • (?ixm-ixm: )

    括号中的i选项、x选项、m选项的开关。在括号范围内有效。

    re = /A(?i:a)A/
    p re =~ "AaA"         # => 0
    p re =~ "AAA"         # => 0
    p re =~ "AAa"         # => nil
    

后方参考

正则表达式 \1 \2 ... \n 表示后方参考。\n表示将匹配第n个括号(正则表达式的()表示群)的内容保存起来,供后面使用。

/((foo)bar)\1\2/

/((foo)bar)foobarfoo/

是一样的。

例:

re = /(foo|bar|baz)\1/
p re =~ 'foofoo'   # => 0
p re =~ 'barbar'   # => 0
p re =~ 'bazbaz'   # => 0
p re =~ 'foobar'   # => nil

对应的括号必须位于后方参考表达式的左侧。

若后方参考表达式位于对应的括号中时,匹配常常会失败。当后方参考表达式中的数字是1位,且没有对应的括号时,匹配也将失败。

p /(\1)/ =~ "foofoofoo" # => nil
p /(foo)\2/ =~ "foo\2"  # => nil

虽然可以指定2位以上的后方参考表达式,但是不要把它同反斜线表示法 的\nnn(对应于8进制数nnn的字符)混为一谈。当数字只有1位时,通常是后方参考表达式。当指定了一个超过2位的数字时,若没有对应括号的话,则被看作是8进制代码。

相反地,若在正则表达式中使用1位的8进制代码时,必须以0打头,例如\01等(不可能存在形如\0这样的后方参考表达式,因此不会混淆)。

p   /\1/ =~ "\1"   # => nil     # 无对应括号的后方参考
p  /\01/ =~ "\1"   # => 0       8 进制代码
p  /\11/ =~ "\11"  # => 0       8 进制代码

# 8 进制代码 (因为没有对应括号)
p /(.)\10/ =~ "1\10" # => 0

# 后方参考 (因为有对应的括号)
p /((((((((((.))))))))))\10/ =~ "aa"  # => 0

# 8 进制代码 (因为没有像"\0" + "8" -> \08 这样的8进制代码)
p /(.)\08/ =~ "1\0008" # => 0

# 如果想在后方参考表达式之后插入数字的话,就必须使用括号加以分隔。
p /(.)(\1)1/ =~ "111"   # => 0

字符范围

正则表达式 [] 负责指定字符范围。这将匹配 [] 内列出的任何一个字符。

例如/[abc]/表示只要匹配"a", "b", "c"中任何一个即可。也可以按照ASCII代码顺序,在连续的字符串之间插入“-”后写成/[a-c]/也是一样的效果。另外,若头上是“^”的话,表示要匹配指定字符之外的一个字符。

若“^”不在头上的话,表示匹配该字符本身。同时,当“-”出现在头或尾上时,表示匹配该字符本身。

p /[a^]/ =~ "^"   # => 0
p /[-a]/ =~ "-"   # => 0
p /[a-]/ =~ "-"   # => 0
p /[-]/ =~ "-"   # => 0

空的字符范围将引发错误。

p /[]/ =~ ""
p /[^]/ =~ "^"
# => invalid regular expression; empty character class: /[^]/

当“]”出现在头上(或否定的“^”之后)时,表示“]”本身,而并非字符范围的结尾。

p /[]]/ =~ "]"       # => 0
p /[^]]/ =~ "]"      # => nil

可以使用反斜线对"^", "-", "]" 以及 "\\"(反斜线)进行转义,使其匹配该字符本身。

p /[\^]/ =~ "^"   # => 0
p /[\-]/ =~ "-"   # => 0
p /[\]]/ =~ "]"   # => 0
p /[\\]/ =~ "\\"  # => 0

在[]中可以使用反斜线表示法 以及正则表达式\w, \W, \s, \S, \d, \D (这些都是表示字符范围的简写法)。

请注意,下列包含否定意味的字符范围也将匹配换行符(正则表达式 \W,\D 也是如此)。

p /[^a-z]/ =~ "\n"    # => 0

字符范围中也可以使用下列特殊的表达法,但是,将来这些表达法是否会继续得到支持还未可知(所以此处从略,欲知详情请参考grep(1) 的手册)。

[:alnum:]  数字和字母 0-9a-zA-Z
[:alpha:]  字母 a-zA-Z
[:blank:]  空白类
[:cntrl:]  控制字符
[:digit:]  数字
[:graph:]  除空白以外的可打印可视字符
[:lower:]  小写字母
[:print:]  可视字符
[:punct:]  符号
[:space:]  空白字符
[:upper:]  大写字母
[:xdigit:] 16进制字符

例: (包括"[]"在内,"[:...:]"表示1个字符。并非文字类的"[]")

p /[[:alnum:]][[:cntrl:]]/ =~ "a\x01"  # => 0

注: 全角字符不在考虑范围之内。即使指定让正则表达式对汉字进行匹配时,[:alpha:]等也不会匹配全角的字母。

p /[[:alpha:]]/e =~ "A"        # => nil

回缩(backtrack)

用特殊括号(?> )将正则表达式括起来后,与该正则表达式相匹配的字符串中的回缩功能就将失效。举例如下。

例如在通常的正则表达式中

p /(a*)ab/ === 'aaab'

是匹配的。该匹配过程如下所示。

  1. 正则表达式 a* 从索引0开始匹配3个a
  2. 正则表达式 a 匹配失败
  3. 正则表达式 a* 将匹配部分稍稍“缩小”一下,匹配2个a(使用了回缩功能)
  4. 正则表达式 a 与字符a匹配
  5. 正则表达式 b 与字符b匹配
但是,如果用括号(?> )把正则表达式括起来的话,就不再匹配了。详细过程如下。
  1. 正则表达式 a* 从索引0开始匹配3个a
  2. 正则表达式 a 匹配失败
  3. a* 想把匹配部分回缩一下,但由于特殊括号的作用,回缩功能失效。
  4. 正则表达式 a* 从索引1开始匹配2个a

接下来的匹配都不成功,最终导致整体匹配失败。

简单说来,通常的正则表达式是“贪婪型的匹配”,而(?> )则是“超贪婪型的匹配”,因为它一旦匹配成功就决不放手。

范例

为了便于您拷贝使用,我们将其代入到以$re_开头的全局变量中。

数值

  • 浮点数(包括整数)

    $re_float = /[-+]?(?:[0-9]+(\.[0-9]*)?|(\.[0-9]+))([eE][-+]?[0-9]+)?/
    
    p $re_float =~ "1.23"    # => 0
    p $&.to_f                # => 1.23
    p $re_float =~ ".23"     # => 0
    p $&.to_f                # => 0.23
    p $re_float =~ "1.23e1"  # => 0
    p $&.to_f                # => 12.3
    p $re_float =~ "1.23e-1" # => 0
    p $&.to_f                # => 0.123
    

用逗号将数字划分成3位一组的形式

  • 方法1:使用回行和先行的方法(回行(lookbehind)需要Oniguruma库的支持)

    p "tone of 12345Hz".gsub(/(?<=\d)(?=(?:\d\d\d)+(?!\d))/, ',')
    => ruby 1.8.0 (2003-08-07) [i586-linux]
       "tone of 12,345Hz"
    
  • 方法2:只使用先行的方法

    p "tone of 12345Hz".gsub(/(\d)(?=(?:\d\d\d)+(?!\d))/, '\1,')
    => ruby 1.8.0 (2003-08-07) [i586-linux]
       "tone of 12,345Hz"
    
  • 方法3:不使用先行的方法

    s = "tone of 12345Hz"
    nil while s.gsub!(/(.*\d)(\d\d\d)/, '\1,\2')
    p s
    => ruby 1.8.0 (2003-08-07) [i586-linux]
       "tone of 12,345 Hz"
    

分享到:
评论
1 楼 qianjigui 2014-01-20  
更全面的文档:
http://www.5wpc.info/it/technical/language/ruby/2014/01/15/Regular/

相关推荐

    ruby正则表达式规则

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

    ruby正则表达式

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

    正则表达式经典实例

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

    精通正则表达式 中英文

    如今,正则表达式已经成为众多语言及工具——Perl、PHP、Java、Python、Ruby、MysQL、VB.NET和c#(以及.NET Framework中的任何语言)——中的标准特性,依靠它,你能以之前完全不敢设想的方式进行复杂而精巧的文本...

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

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

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

    如今,正则表达式已经成为众多语言及工具--Perl、PHP、Java、Python、Ruby、MysQL、VB-NET和c#(以及.NETFramework中的任何语言)--中的标准特性,依靠它,你能以之前完全不敢设想的方式进行复杂而精巧的文本处理。...

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

    如今,正则表达式已经成为众多语言及工具——Perl、PHP、Java、Python、Ruby、MysQL、VB-NET和c#(以及.NETFramework中的任何语言)——中的标准特性,依靠它,你能以之前完全不敢设想的方式进行复杂而精巧的文本...

    正则表达式完整高清版

    《正则指引》针对作者在开发中遇到的实际问题,以及其他开发人员咨询的问题,总结出一套使用正则表达式解题的办法,并通过具体的例子指导读者拆解、分析问题。全书分为三大部分:第一部分主要讲解正则表达式的基础...

    正则表达式经典实例.pdf

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

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

    如今,正则表达式已经成为众多语言及工具——Perl、PHP、Java、Python、Ruby、MySQL、VB.NET和C#(以及.NET Framework中的任何语言)——中的标准特性,依靠它,你能以之前完全不敢设想的方式进行复杂而精巧的文本...

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

    如今,正则表达式已经成为众多语言及工具——Perl、PHP、Java、Python、Ruby、MySQL、VB.NET和C#(以及.NET Framework中的任何语言)——中的标准特性,依靠它,你能以之前完全不敢设想的方式进行复杂而精巧的文本...

    精通正则表达式~~~

    精通正则表达式第三版 搜集于网络 前言..........I 第1章:正则表达式入门.... 1 解决实际问题... 2 作为编程语言的正则表达式... 4 以文件名做类比... 4 以语言做类比... 5 正则表达式的知识框架... 6 对于...

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

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

    ruby 正则表达式详解及示例代码

    在编写puppet的pp文件中,会用到很多ruby的正则表达式,常用的正则如下: 正则表达式: [codesyntax lang=”ruby”] {}: 重复次数(如 {4}表示前面的会重复出现恰好4次) {m,n}: 前面元素最少出现m次,最多出现n次 []...

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

    《正则表达式经典实例》对于如何使用正则表达式来解决一些常见的问题给出了按部就班的解决方案,其中包括C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET的实例。  《正则表达式经典实例》主要包括以下...

    正则表达式框架OgreKit.zip

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

Global site tag (gtag.js) - Google Analytics