Ruby字符串(1):String基本用法
String字符串字符串由String类提供,除了直接使用单双引号或其它字面量创建字符串,也可以使用String.new()方法来创建。 a = "hello" b = String.new("world") Ruby中的字符串是可变对象。 字符串的连接直接连接即可: >> "a""b" => "ab" >> "a" "b" => "ab" >> "a" "b" => "ab" 单双引号这和Perl一样,和Shell也类似。单引号是强引用,双引号是弱引用。 双引号的一个特性是支持表达式、变量内插,使用#符号即可。在Ruby中,
所以,在双引号中如果 格式化字符串内插Ruby显然也是支持printf、sprintf的,但是Ruby除了表达式或变量内插,还支持格式化字符串内插。 sprintf "pi is about %.4f",Math::PI => "pi is about 3.1416" "pi is about %.4f" % Math::PI # 单个格式化字符串 => "pi is about 3.1416" "%s: %f" % ["pi",Math::PI] # 多个格式化字符串 => "pi: 3.141593" "xiaomage = %{age}" % {:age => "23"} => "xiaomage = 23" 正如上面的示例,需要进行格式化的字符使用 %q和%Q和%这和Perl里的
# 以下等价,内部的单引号不需要反斜线转义 %q(hello'world) %q[hello'world] %q{hello'world} %q!hello'world! %q#hello'world# # 以下等价 %Q(hello'world) %Q[hello'world] %{hello'world} # 单个%是一样的 %!hello'world! %#hello'world# 如果使用的是成对的定界符,那么在定界符内只要合理的配对,就可以包含定界符字面符号。例如: %Q(hello(hello world)world) %<<book>Ruby</book>> %((1+(2*3)) = #{(1+(2*3))}) %(A mismatched paren ( must be escaped) # 不配对的括号需要转义 关于字符串的可变性对于Ruby来说,字符串是可变的。所以,无法使用单个对象来引用内容相同的两个字符串,如果能引用的话,其中一个修改了就表示另一个字符串也会修改,但这已经表示同一个对象了。 所以,只要Ruby遇到一个字符串,都会新创建一个字符串对象。这意味着,如果在一个循环中使用了字符串常量,那么这个常量字符串对象也会在每次循环过程中新创建,而这是可以避免的消耗性能的一种方式。 >> 10.times {puts "test".object_id} 12046480 12046340 12046280 12046220 12046160 12046080 12046000 12045880 12045780 12045680 单字符使用一个问号作为下一个字符的前缀,这个字符将称为字符字面量。例如: ?A # 代表一个大写字母A ?? # 代表一个问号 ?" # 代表一个双引号 在Ruby1.8及之前的版本,这是一个单字符序列,会转换成ASCII码存放,在Ruby 1.9之后,单字符等价于只有一个字符的字符串。 >> ?A == 'A' => true 扩展字符串:+ * <<想要连接两个字符串,直接不使用任何连接符或使用"+"就可以。但注意,它们不会自动将其它类型转换成字符串类型,需要手动调用to_s方法来转换。 >> "A""B" => "AB" >> "A"+"B" => "AB" >> "A"2 # SyntaxError: >> "A"+2 # TypeError >> "A"+2.to_s => "A2" 可使用"<<"将多个字符串追加到某个字符串的尾部,它同样不会自动转换成字符串。这时候字符串就像是一个字符数组一样,但需要知道,Ruby字符串不是字符数组,只是实现了一些好用的操作字符串的方法: >> "abc" << "hello" <<"world" => "abchelloworld"
>> "xyz" << 65 => "xyzA" 只是需要注意的是,使用 >> a="xyz" => "xyz" >> a + "XYZ" => "xyzXYZ" >> a # a没有变 => "xyz" >> a << "XYZ" => "xyzXYZ" >> a # a已经变了 => "xyzXYZ"
>> "ab" * 3 => "ababab" >> '-' * 40 => "----------------------------------------" 字符串的索引属性字符串可变、可索引子串、设置子串、插入子串、删除子串等等。 字符串[]()搜索和赋值通过 # 1.根据索引,搜索或赋值单元素 str[index] → new_str or nil str[index] = new_str # 2.根据索引和给定长度,搜索或赋值0或多个元素 str[start,length] → new_str or nil str[start,length] = new_str # 3.根据索引范围,搜索或赋值0或多个元素 str[range] → new_str or nil str[range] = aString # 4.根据正则模式(斜线包围正则表达式),搜索或赋值匹配到的元素 str[regexp] → new_str or nil str[regexp] = new_str # 5.根据正则模式(包含分组匹配),返回给定分组内容 # capture可以是分组名,也可以是分组索引号(即反向引用) # 分组索引号为0表示regexp匹配的所有内容 # 如果是赋值操作,则替换给定分组的内容 str[regexp,capture] → new_str or nil str[regexp,integer] = new_str str[regexp,name] = new_str # 6.根据给定字符串精确搜索或赋值 str[match_str] → new_str or nil str[other_str] = new_str 可以说,Ruby对字符串的索引操作支持的是相当的丰富、完善。下面是一些例子: a = "hello there" a[1] #=> "e" a[2,3] #=> "llo" a[2..3] #=> "ll" a[-3,2] #=> "er" a[7..-2] #=> "her" a[-4..-2] #=> "her" a[-2..-4] #=> "" a[11,0] #=> "" a[11] #=> nil a[12,0] #=> nil a[12..-1] #=> nil a[/[aeiou](.)1/] #=> "ell" a[/[aeiou](.)1/,0] #=> "ell" 等价于上面方式 a[/[aeiou](.)1/,1] #=> "l" 第一个分组内容 a[/[aeiou](.)1/,2] #=> nil 第二个分组 a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/,"non_vowel"] #=> "l" a[/(?<vowel>[aeiou])(?<non_vowel>[^aeiou])/,"vowel"] #=> "e" a["lo"] #=> "lo" a["bye"] #=> nil s = "hello" while(s["l"]) # 将所有的l替换成L s["l"] = "L" end 与索引搜索、索引赋值(包括替换、插入、删除元素)、索引检查元素是否存在等操作有一些相对应的String方法。如下。 include?()字符串中是否存在某子串。 include? other_str → true or false "hello".include? "lo" #=> true "hello".include? "ol" #=> false "hello".include? ?h #=> true index()搜索某子串或匹配的子串的索引位置。 index(substr[,offset]) → int or nil index(regexp[,offset]) → int or nil 例如: "hello".index('e') #=> 1 "hello".index('lo') #=> 3 "hello".index('a') #=> nil "hello".index(?e) #=> 1 "hello".index(/[aeiou]/,-3) #=> 4 replace()替换字符串为另一个字符串,它会替换掉全部内容。它会原处修改字符串。 replace(other_str) → str s = "hello" #=> "hello" s.replace "world" #=> "world" insert()在字符串中某个位置处开始插入另一个字符串。它会原处修改字符串。 insert(index,other_str) → str "abcd".insert(0,'X') #=> "Xabcd" "abcd".insert(3,'X') #=> "abcXd" "abcd".insert(4,'X') #=> "abcdX" "abcd".insert(-3,'X') #=> "abXcd" "abcd".insert(-1,'X') #=> "abcdX" 字符串的迭代因为字符串支持索引操作,所以可以直接通过索引的方式进行迭代。 a="hello" i=0 while(i<a.length) do puts a[i] i += 1 end 0.upto(a.size - 1 ) do |x| print a[x] end 可以将字符串split成数组,然后通过each迭代。注意,Ruby 1.9里字符串不能直接通过each迭代了,它不再max-in Enumerable中的each。 a="hello" a.split("").each do |x| puts x end Ruby的字符串类中还定义了4个迭代方式:each_byte、each_char、each_line、each_codepoint。最常用的,显然是each_char。 a = "hello" a.each_char do |x| puts x end each_byte、each_codepoint迭代时,得到的是各字符的ASCII码或Unicode代码点。 "我".each_byte.to_a #=> [230,136,145] "我是单身狗".each_byte.to_a #=> [230,145,230,152,175,229,141,# 149,232,186,171,231,139,151] "我".each_codepoint.to_a #=> [25105] "我是单身狗".each_codepoint.to_a #=> [25105,26159,21333,36523,29399] 按块读取数据(或按段落读取)时,很可能会用上each_line来迭代缓冲中的一大段数据的每一行。 each_line(separator=$/ [,getline_args]) {|substr| block } → str 每迭代,都将该行传递到代码块中。 其中:
str="a linenb linenc linen" str.each_line {|x| puts "#{x}"} # 输出: =begin a line b line c line =end 下面是使用 str="a linenb linenc linen" str.each_line(chomp: true) {|x| puts "#{x}: #{x.length}"} # 输出: =begin a line: 6 b line: 6 c line: 6 =end # 等价于 str.each_line {|x| x.chomp!();puts "#{x}: #{x.length}" } # 输出: =begin a line: 6 b line: 6 c line: 6 =end 下面是指定行分隔符的用法。 str="a linenb linenc linen" str.each_line("e") {|x| puts "-#{x}-"} # 输出: =begin -a line- - b line- - c line- - - =end # 指定分隔符和chomp参数的时候 str.each_line("e",chomp:true) {|x| puts "-#{x}-"} -a lin- - b lin- - c lin- - - 字符串的比较Ruby中典型的几种方法: 其中,对于纯字符串对象,
此外,String类还实现了 casecmp(other_str) → -1,+1,or nil casecmp?(other_str) → true,false,or nil 例如: "1234abc".casecmp("1234ABC") #=> 0 "我".casecmp("我") #=> 0 "u{c4 d6 dc}" #=> "??ü" "u{e4 f6 fc}" #=> "??ü" "u{c4 d6 dc}".casecmp("u{e4 f6 fc}") #=> -1 "u{c4 d6 dc}".casecmp?("u{e4 f6 fc}") #=> true (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |