字符串方法

到目前为止,我们在处理字符串时使用了 Regexp 类的方法。事实上,由于 String 类有一些自己的正则表达式方法,因此模式匹配可以双向进行。这些包括 =~match(所以你可以在匹配时切换 String 和 Regexp 对象的顺序),以及遍历字符串的 scan 方法,该方法寻找尽可能多的匹配。每个匹配都添加到一个数组中。例如,我正在寻找字母 ‘a’,’b’ 或 ‘c’ 的匹配。match 方法返回的 MatchData 对象中包含第一个匹配项(’a’);但 scan 方法会继续扫描字符串并在数组中返回它找到的所有匹配项:

match_scan.rb
  1. TESTSTR = "abc is not cba"
  2. puts( "\n--match--" )
  3. b = /[abc]/.match( TESTSTR ) #=> MatchData: "a"
  4. puts( "--scan--" )
  5. a = TESTSTR.scan(/[abc]/) #=> Array: ["a", "b", "c", "c", "b", "a"]

可选地,可以给 scan 方法传递一个块,以便可以以某种方式处理后扫描创建的数组元素:

  1. a = TESTSTR.scan(/[abc]/){|c| print( c.upcase ) } #=> ABCCBA

许多其它 String 方法可以与正则表达式一起使用。String.slice 方法的一个版本接受一个正则表达式作为参数并返回任何匹配到的子字符串。String.slice! 方法(注意最后的 !)从接收字符串中删除匹配的子字符串并返回子字符串:

string_slice.rb
  1. s = "def myMethod # a comment "
  2. puts( s.slice( /m.*d/ ) ) #=> myMethod
  3. puts( s ) #=> def myMethod # a comment
  4. puts( s.slice!( /m.*d/ ) ) #=> myMethod
  5. puts( s ) #=> def # a comment

split 方法基于模式(pattern)将字符串拆分为子字符串。结果(减去模式)作为数组返回;空模式将字符串拆分为字符:

string_ops.rb
  1. s = "def myMethod # a comment"
  2. p( s.split( /m.*d/ ) ) # => ["def ", " # a comment"]
  3. p( s.split( /\s/ ) ) #=> ["def", "myMethod", "#", "a", "comment"]
  4. p( s.split( // ) ) # => ["d", "e", "f", " ", "m", "y", "M", "e", "t", "h", "o", "d", " ", "#", " ", "a", " ", "c", "o", "m", "m", "e", "n", "t"]

你可以使用 sub 方法匹配正则表达式,并将其第一个匹配项替换为字符串。如果未匹配到,则返回不变的字符串:

  1. s = "def myMethod # a comment"
  2. s2 = "The cat sat on the mat"
  3. p( s.sub( /m.*d/, "yourFunction" ) ) #=> "def yourFunction # a comment"
  4. p( s2.sub( /at/, "aterpillar" ) ) #=> "The caterpillar sat on the mat"

sub! 方法与 sub 类似,但会修改原始(接收)字符串。或者,你可以使用 gsub 方法(或 gsub! 来修改接收字符串)用字符串替换所有出现的模式匹配项:

  1. p( s2.gsub( /at/, "aterpillar" ) ) #=> "The caterpillar saterpillar on the materpillar"