Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6099393
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: Python/Ruby

2013-09-14 11:24:27


正在表达式与字符串的操作

要在高级层面处理字符串,必须学会正则表达式,其实,正则表达式就是搜索查询,ruby在对某个很长的字符串运

行该查询,就能得到你期望的内容,这样看来,正则表达式也是一个字符串,代表规则的字符串,按照这种规则可

指定的对象上找出相匹配的的元素。


替换

对于字符串,这是经常的操作之一,把某些内容替换为其它内容,如:
puts "foobar".sub('bar','foo')

irb(main):071:0> puts "foobar".sub('bar','foo')
foofoo
=> nil

本例中,使用对字符串调用的sub方法,该方法把第一次遇到的‘bar’替换为‘foo’,替换的结果为foofoo。

sub方法只对发现的第一个匹配文本做一次替换,而gsub方法则对所有匹配文本进行多次替换,如:

irb(main):072:0> puts "This is a test".gsub('i','')
Ths s a test
=> nil
这里把所有字母‘i’替换成空字符串,只匹配字符‘i’ 不是真正的正则表达式,如,把字符串开头两个字符替

换成'Hello':

irb(main):073:0> x = "This is a test"
=> "This is a test"
irb(main):074:0> puts x.sub(/^../ , 'Hello')
Hellois is a test
=> nil

本例中,使用sub的方法进行了单个替换,传递给sub方法的第一个参数不是字符串,而是一个正则表达式,斜

杠"/"用于表示正则表达式的开头和结尾。在正则表达式^..中,^称为锚,表示正则表达式将从字符中的任一行开

头进行匹配。至于..,每个点都表示"任何字符",综上可知,/^../表示”某行开始的开头两个字符“,所以“Th

”被替换成了Hello。我们如果想将行尾的两个字符替换成Hello,怎么办呢?与^相反,$就是从行尾进行匹配的,

直接将第一个参数改为:/..$/即可实现。

使用正则表达式进行迭代

如果想访问字符串的各个部分,应该怎么办?scan正是所需要的迭代子方法:

“xyz”.scan(/./) {|letter| puts letter}

irb(main):077:0> "xyz".scan(/./) {|letter| puts letter}
x
y
z
=> "xyz"

在字符串中难免出现空格,如果只匹配字母或数字,正则表达式中使用\w即可,\w代表“字母表中的任何字符或下

划线”,如下:

irb(main):081:0> "This is a test".scan(/\w\w/) { |x|  puts x}
Th
is
is
te
st
=> "This is a test"

正则表达式中基本的特殊字符和符号

^  用于行开始的锚
$  用于行结束的锚
\A 用于字符开始的锚
\Z 用于字符结束的锚
.  任意字符
\w 任何字母、数字或下划线
\W  不匹配\w的任何内容
\d  任何数字
\D  不匹配\d的内容
\s  空白(空格、制表符、换行符等)
\S  非空白(任何可见字符)


正则表达式字符和子表达式修饰符

*     匹配零次或多次前面紧跟的字符,并尽量多地匹配
+     匹配一次或多次前面紧跟的字符,并尽量多地匹配
*?   匹配零次或多次前面紧跟的字符,并尽量少地匹配
+?   匹配一次或多次前面紧跟的字符,并尽量少地匹配
?    要么匹配一次,要么全不匹配前面紧跟的字符
{x}   匹配x次前面紧跟的字符
{x,y} 匹配最少x次、最多y次前面紧跟的字符

关于正则表达式,需要理解字符类别(character classes),这些字符类别让可以针对特定字符集合进行匹配。

例如,可以扫描字符串中所有元音字符:

“This  is a test”.scan(/[aeiou]/) { |x| puts x}

匹配任何字符,可以在[]指定字符范围,如[a-m]
irb(main):002:0> "This is a test".scan(/[a-m]/) { |x| puts x }
h
i
i
a
e
=> "This is a test"

匹配查询

做替换和从字符串中解析某些文本是很有用的,但有时我们只想检查某个字符串是否匹配所选择的模式。例如,可

能想快速得知字符串是否包含元音字母

puts “String has vowels”if "This is a test" =~ /[aeiou]/

irb(main):001:0> puts "String has vowels" if "This is a test" =~ /[aeiou]/
String has vowels
=> nil

=~是另一种运算符,即匹配查询运算符。如果字符串与后面的正则表达式相匹配,则该表达式结果为true。也可做

相反的操作:
puts “String cotains no digits”unless "This is a test" =~/[0-9]/  其含义是除非0到9的数字匹配测试字

符串,否则就告诉用户,字符串中没有数字。

irb(main):001:0> puts "String contains no digits" unless "This is a test" =~ [0-9]
String contains no digits
=> nil
 还可以使用String类提供的match的方法,=~是根据正则表达式是否匹配字符串,返回true 或false,而match方

法则提供了许多更强大的能力,如:

puts "String has vowels" if "This is a test".match(/[aeiou]/)

该例子看起来与前面的例子几乎一样,但match方法不需要用正则表达式作为参数,它把提供给它的任何字符串都

转换成正则表达式,因此也可以这么写:

puts "String has vowels" if "This is a test".match("[aeiou]")

如果正则表达式由用户提供,或从文件及其他外部来源载入,这种功能是非常有用的。


在正则表达式中,如果其中一部分由括号包围,则该部分正则表达式所匹配的数据可以单独使用,与剩余的其它数

据不相干。match方法让你可以访问这些数据:

irb(main):001:0> x = "This is a test".match(/(\w+) (\w+)/)
=> #
irb(main):002:0> puts x[0]
This is
=> nil
irb(main):003:0> puts x[1]
This
=> nil
irb(main):004:0> puts x[2]
is
=> nil


match方法返回MatchData对象,该对象的访问方法与数组类似。第一个元素包含整个正则表达式所匹配的数据,但

每个后续元素都只包含正则表达式每块单元所匹配的内容。在本例中,第一块(\w+)匹配This,第二块(\w+)匹配

is。

阅读(580) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~