您的位置:首页 > 其它

Recipe 1.8. Processing a String One Character at a Time

2009-11-06 23:22 453 查看
If you're processing an ASCII document, then each byte corresponds to one character. Use String#each_byte to yield each byte of a string as a number, which you can turn into a one-character string:

1 'foobar'.each_byte { |x| puts "#{x} = #{x.chr}"}
2 #102 = f
3 #111 = o
4 #111 = o
5 #98 = b
6 #97 = a
7 #114 = r

Use String#scan to yield each character of a string as a new one-character string:

1 'foobar'.scan(/./) { |c| puts c}
2 #f
3 #o
4 #o
5 #b
6 #a
7 #r

Since a string is a sequence of bytes, you might think that the String#each method would iterate over the sequence, the way Array#each does. But String#each is actually used to split a string on a given record separator (by default, the newline):

1 "foo\nbar".each { |x| puts x }
2 #foo
3 #bar

String#each_byte is faster than String#scan, so if you're processing an ASCII file, you might want to use String#each_byte and convert to a string every number passed into the code block (as seen in the Solution).

If you have the $KCODE variable set correctly, then the scan technique will work on UTF-8 strings as well. This is the simplest way to sneak a notion of "character" into Ruby's byte-based strings.

1 french = "\xc3\xa7a va"
2
3 french.scan(/./) { |c| puts c }
4 #
5 #
6 # a
7 #
8 # v
9 # a
10
11
12 french.scan(/./u) { |c| puts c }
13 # ç
14 # a
15 #
16 # v
17 # a
18
19
20 $KCODE = 'u'
21 french.scan(/./) { |c| puts c }
22 # ç
23 # a
24 #
25 # v
26 # a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: