Ruby 请教:ruby 如何截取 140 个字,中英文逗号啥的都有

benyhu · 2012年05月31日 · 最后由 larryzhao 回复于 2012年06月07日 · 6305 次阅读

发到新浪微博用的

没有回答,是问题太简单了吗

#2 楼 @heliang7 140 个字,不是 140 个字符

做了下实验,结果有点怪。


1.9.2p320 :001 > a = "\u6c34\u6d52\u4f20"
 => "水浒传" 
1.9.2p320 :002 > a.truncate(1)
 => "水..." 
1.9.2p320 :003 > a = "\u6c34some??\u6d52\u4f20"
 => "水some??浒传" 
1.9.2p320 :004 > a.truncate(3)
 => "..." 
1.9.2p320 :005 > a.truncate(4)
 => "水..." 
1.9.2p320 :006 > a.truncate(5)
 => "水s..." 
1.9.2p320 :007 > 

在新浪微博客里面: "m" => 1 个字 "mm" => 1 个字 "好" => 1 个字 "好吗" => 2 个字

貌似一个英文字符算半个字

如果按字节来算,一个中文字是三个字节,一个英文字是一个字节,不知到新浪是如何算这 140 个字的

# encoding: utf-8

str = "水浒传abcdef水浒传"

puts str.scan(/./)[0, 3] # =>水浒传
puts str.scan(/./)[0, 4] # =>水浒传a
puts str.scan(/./)[0, 10] # =>水浒传abcdef水

不过我感到奇怪的是,在我写的一个发推的 web 程序里面

def twitter
  twitter =  params[:twitter].to_s #从form里面的到输入的文字
  twitter = twitter[0, 137] + '...' if twitter.size > 140

  Twitter.update(twitter, :in_reply_to_status_id=>params[:since_id])

  redirect_to :action => 'timeline'
end

这样是能直接截断发 140 个文字来着,也是中英文数字标点符号混合

ruby 1.9 直接可以 ruby 1.8 用 activesupport 提供的 mb_chars,好像 truncate 已经内置使用了

匿名 #10 2012年05月31日

#6 楼 @benyhu 新浪的可以这样做..

#coding=utf-8
#n为要截取的长度
n = 4
puts "水浒传sudhgsdug".encode("gbk").force_encoding("binary")[0...n * 2].force_encoding("gbk").encode("utf-8")

#9 楼 @Rei 新浪的长度计算比较淫荡,英文字符和半角符号都算半个字。按这个规则,如果最大长度为 5,直接 'hello world'[0,5] 其实有点浪费,'hello world'[0,10] 也是能放得下的。

#11 楼 @dotnil 又是这种奇葩的设定……是我就无视了,浪费就浪费了

PS: 裁字问题的一个汇总文章 http://rubylution.herokuapp.com/topics/10

将多字节字符替换为两个单字节字符,比如 "水 abc" => "aaabc", 然后计算新字符串长度 ''aaabc".length => 5

我觉得楼主可以查看一下twitter-text-rb这个项目https://github.com/twitter/twitter-text-rb

之前用到过一下,里面 twitter 计算混合字符长度是用ActiveSupport::Multibyte::Chars来做的,

项目之余简单做了一下实验,不知道如下是不是可以帮助到楼主 (ActiveSupport::Multibyte::Chars这个类的 truncate 自动添加了...):

jruby-1.6.7 :019 > text1 = "\u6c34some??\u6d52\u4f20"
 => "水some??浒传" 
jruby-1.6.7 :020 > text2 = ActiveSupport::Multibyte::Chars.new(text1).normalize(:c)
 => #<ActiveSupport::Multibyte::Chars:0x458176ff @wrapped_string="水some??浒传"> 
jruby-1.6.7 :021 > text2.length
 => 9 
jruby-1.6.7 :022 > text2.truncate(5)
 => #<ActiveSupport::Multibyte::Chars:0x4717e412 @wrapped_string="水s..."> 

可以看到中英混在一起可以正确的计算出长度,然后按照你给出的长度进行截取后会自动补全...,还是挺方便的吧

回完发现@Rei 之前已经提到了,spammer 了..

需要 登录 后方可回复, 如果你还没有账号请 注册新账号