正则表达式
下面就来讲讲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'
是匹配的。该匹配过程如下所示。
- 正则表达式 a* 从索引0开始匹配3个a
- 正则表达式 a 匹配失败
- 正则表达式 a* 将匹配部分稍稍“缩小”一下,匹配2个a(使用了回缩功能)
- 正则表达式 a 与字符a匹配
- 正则表达式 b 与字符b匹配
- 正则表达式 a* 从索引0开始匹配3个a
- 正则表达式 a 匹配失败
- a* 想把匹配部分回缩一下,但由于特殊括号的作用,回缩功能失效。
- 正则表达式 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"
相关推荐
- **命令行工具**:如 grep、sed、awk 等,是Linux和Unix系统中的强大文本处理工具,支持正则表达式操作。 - **编程语言支持**:几乎所有的编程语言都内置了正则表达式库,如Python的`re`模块、JavaScript的`match...
5. **参考手册**:RegexBuddy.chm是该软件的帮助文件,包含了详细的正则表达式语法和函数说明,方便用户随时查阅。 6. **便捷操作**:提供的`.bat`脚本文件可能用于快速启动或自动化某些任务,而`.jgcscs`文件则...
### Ruby中的正则表达式详解:字符串匹配与替换操作 #### 一、引言 正则表达式(Regular Expression)是一种强大的模式匹配工具,在多种编程语言中都有...希望本文能为学习Ruby正则表达式的朋友们提供有用的参考。
正则表达式(Regular Expressions)是一种强大的文本处理工具,在多种编程语言和工具中都有广泛的应用,例如Perl、Python、Ruby、Java、VB.NET、C#(通过.NET框架)、PHP以及MySQL等。正则表达式允许用户创建复杂的...
8. **正则表达式**:Ruby的Regexp类提供了强大的文本匹配和操作功能,支持多种正则表达式语法。 9. **块和迭代器**:Ruby中的块(采用do..end或{}语法)和迭代器(如each、map等)是处理集合数据的重要工具。 10. ...
7. **正则表达式(Regexp)**:Ruby内置了强大的正则表达式支持,用于文本匹配和处理。 8. **文件和I/O操作**:学习如何读写文件,以及进行标准输入输出和流处理。 9. **线程和并发**:Ruby支持多线程,文档会解释...
9. **正则表达式**:Ruby内置了强大的正则表达式引擎,提供了丰富的匹配和替换功能。 10. **文件和I/O操作**:Ruby提供了方便的API进行文件读写和系统级I/O操作,如File、Dir、IO等类。 11. **线程和并发**:Ruby...
- 正则表达式:`Regexp`类提供了正则表达式操作,用于文本匹配和替换。 4. **元编程** - 动态定义:Ruby允许在运行时定义类和方法,体现了高度的灵活性。 - 类方法和实例方法:`class 和`self.method`用于定义类...
6. **正则表达式**:掌握Ruby中的正则表达式,用于文本匹配和处理。 7. **模块与命名空间**:理解模块如何帮助组织代码和避免命名冲突。 8. **元编程**:探索Ruby的send方法、class_eval、instance_eval等元编程技巧...
此外,还会涉及异常处理、文件操作、正则表达式和字符串处理等内容,这些都是Ruby编程的基础。 2. **Ruby参考手册**: 这部分通常是对Ruby内置类库、方法、语法的详细参考,涵盖了标准库的所有模块和类,比如Array...
2. **基础数据类型操作**:这部分内容涵盖了数字、字符串、正则表达式以及日期等低级数据类型的处理方法。 3. **正则表达式引擎(Oniguruma)**:介绍了一种新的正则表达式处理引擎,提高了处理效率和灵活性。 4. ...
- **正则表达式**:介绍Ruby中的正则表达式使用方法。 - **块和迭代器**:解释块的使用以及常见的迭代器操作。 - **文件读写**:展示如何在Ruby中进行文件输入输出操作。 - **命令行参数**:说明如何处理命令行传入...
4. **字符串和正则表达式**:Ruby提供了丰富的字符串操作方法,以及强大的正则表达式库,书中有专门的章节来讨论这些内容。 5. **文件和I/O操作**:Ruby提供了方便的文件和I/O操作接口,书里会讲解如何读写文件、...
根据描述中的关键词“javascript script 脚本 正则表达式”,我们可以进一步探讨相关知识点: 1. **JavaScript**: - JavaScript是一种广泛应用于网页开发的脚本语言,可以实现动态效果和交互功能。 - 了解...
- **正则表达式**: Ruby 支持强大的正则表达式功能,可以用于模式匹配和文本处理。 - **块(Block)和迭代器(Iterator)**: 块是Ruby中的一种代码块,可以作为参数传递给方法;迭代器则是用于遍历集合的机制。 - **读写...