在用otto处理字符串的时候遇到了一个奇怪的情况,某个带中文的字符串调用substr方法时,即使第二个参数传入字符串的长度,依然可能只截取到一部分。例如:
package main
import (
"github.com/robertkrimen/otto"
)
func main(){
vm := otto.New()
vm.Set("a","测试1234中文")
vm.Run(`
console.log(a,a.length,a.substr(0,a.length))
for(var i=-1;i++<a.length;) console.log(a.charAt(i))
`)
}
输出的结果是:
测试1234中文 8 测试12
测
试
1
2
3
4
中
文
很奇怪,长度获取是正确的,charAt也是正确的,偏偏substr处理时被截断了。
由于golang的string类型并不能处理utf8字符串,遇到utf8的情况下往往用的是[]rune
替代的string
,没去看代码,我猜测这种情况的原因是substr的处理方式是把字符串当成string类型,中文字被当成两个字符。
改otto源代码就算了,既然charAt能取出正确的结果,那么索性把substr的代码改掉:
String.prototype.substr=function(a,b){
var r='',l=this.length;
if(a>l)return r
a=(a+l)%l
for(var i=0;i<Math.min(b===undefined?l:b,l) && a+i<l;i++)
r+=this.charAt(a+i)
return r
}
再次运行这个实例:
package main
import (
"github.com/robertkrimen/otto"
)
func main(){
vm := otto.New()
vm.Set("a","测试1234中文")
vm.Run(`
String.prototype.substr=function(a,b){
var r='',l=this.length;
if(a>l)return r
a=(a+l)%l
for(var i=0;i<Math.min(b===undefined?l:b,l) && a+i<l;i++)
r+=this.charAt(a+i)
return r
}
console.log(a,a.length,a.substr(0,a.length))
for(var i=-1;i++<a.length;) console.log(a.charAt(i))
`)
}
输出结果:
测试1234中文 8 测试1234中文
测
试
1
2
3
4
中
文
相关文档
暂无
随便看看
畅言模块加载中