我相信没有LeftStr(str,n)(最多取n个第一个字符),RightStr(str,n)(最多取n个最后一个字符) 和 SubStr(str,pos,n) (取 pos 后的前 n 个字符)在 Go 中的功能,所以我试着做一个
// take at most n first characters
func Left(str string, num int) string {
if num <= 0 {
return ``
}
if num > len(str) {
num = len(str)
}
return str[:num]
}
// take at most last n characters
func Right(str string, num int) string {
if num <= 0 {
return ``
}
max := len(str)
if num > max {
num = max
}
num = max - num
return str[num:]
}
但我相信当字符串包含 unicode 字符时,这些函数会给出错误的输出。这些功能最快的解决方案是什么,使用 for range 循环是唯一的方法吗?
最佳答案
正如评论中已经提到的, combining characters 、修改 rune 等多种 rune "characters" 可能会造成困难。
任何对 Go 中的 Unicode 处理感兴趣的人都应该阅读 Go 博客文章
"Strings, bytes, runes and characters in Go"
和 "Text normalization in Go" .
特别是,后面会谈到 golang.org/x/text/unicode/norm可以帮助处理其中一些问题的软件包。
您可以考虑从字符串中吐出第一个(或最后一个)“n 个字符”越来越准确(或越来越了解 Unicode)的几个级别。
只需使用 n 个字节。
这可能会在一个 rune 中间拆分,但是 O(1),非常简单,并且在许多情况下您知道输入仅包含单字节 rune 。
例如。 str[:n].
在 n 个 rune 后拆分。
这可能会在一个字符的中间 split 。这可以很容易地完成,但代价是仅使用 string([]rune(str)[:n]) 进行复制和转换。
您可以使用 unicode/utf8 避免转换和复制包的DecodeRuneInString(和DecodeLastRuneInString)函数依次获取前n个 rune 的长度,然后返回str[:sum]( O(n),没有分配)。
在第 n 个“边界”之后拆分。
一种方法是使用
norm.NFC.FirstBoundaryInString(str)反复
或 norm.Iter找到要拆分的字节位置,然后返回 str[:pos]。
考虑显示的字符串“cafés”,它可以在 Go 代码中表示为:“cafés”、“caf\u00E9s”或“caf\xc3\xa9s”,它们都产生相同的六个字节。或者它可以表示为“cafe\u0301s”或“cafe\xcc\x81s”,它们都产生相同的七个字节。
上面的第一个“方法”可能会将它们拆分为“caf\xc3”+“\xa9s”和cafe\xcc“+”\x81s。
第二个可能将它们拆分为 "caf\u00E9"+"s"("café"+"s") 和 "cafe"+"\u0301s"("cafe"+"́s")。
第三个应将它们拆分为“caf\u00E9”+“s”和“cafe\u0301”+“s”(均显示为“café”+“s”)。
关于string - Go 的 LeftStr、RightStr、SubStr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29406316/
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"
玩转ruby,我已经:#!/usr/bin/ruby-w#WorldweatheronlineAPIurlformat:http://api.worldweatheronline.com/free/v1/weather.ashx?q={location}&format=json&num_of_days=1&date=today&key={api_key}require'net/http'require'json'@api_key='xxx'@location='city'@url="http://api.worldweatheronline.com/free/v1/weather.
我有代码:classScenedefinitialize(number)@number=numberendattr_reader:numberendscenes=[Scene.new("one"),Scene.new("one"),Scene.new("two"),Scene.new("one")]groups=scenes.inject({})do|new_hash,scene|new_hash[scene.number]=[]ifnew_hash[scene.number].nil?new_hash[scene.number]当我启动它时出现错误:freq.rb:11:in`[]'
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
我的Ruby代码中有一个看起来有点像这样的结构Parameter=Struct.new(:name,:id,:default_value,:minimum,:maximum)稍后,我使用创建了这个结构的一个实例freq=Parameter.new('frequency',15,1000.0,20.0,20000.0)在某些时候,我需要这个结构的精确副本,所以我调用newFreq=freq.clone然后,我更改newFreq的名称newFreq.name.sub!('f','newF')奇迹般地,它也改变了freq.name!像newFreq.name='newFrequency'这样
我正在重构一个西洋跳棋程序,我正在尝试将玩家移动请求(例如以“3、3、5、5”的形式)处理到一个int数组中。我有以下方法,但感觉不像我所知道的那样像Ruby:deftranslate_move_request_to_coordinates(move_request)return_array=[]coords_array=move_request.chomp.split(',')coords_array.each_with_indexdo|i,x|return_array[x]=i.to_iendreturn_arrayend我用它进行了以下RSpec测试。it"translatesa
每当我尝试运行该程序时,都会弹出一条错误消息“条件字符串文字(第10行)”。我做错了什么?puts"Welcometothebestcalculatorthereis.Wouldyouliketo(a)calculatetheareaofageometricshapeor(b)calculatetheequationofaparabola?Pleaseenteran'a'ora'b'togetstarted."response=gets.chompifresponse=="a"or"A"puts"ok."elsifresponse=="b"or"B"puts"awesome."else
我用这个错误搜索了jekyll。jekyll处理页面时似乎出现了ruby错误,但我根本不了解ruby。杰基尔版本1.3.1我什至重新安装了ruby和jekyll,但结果没有改变。更新:在我将jekyll从1.31降级到1.20后,这个错误消失了注意:我的网站是用jekyll1.20创建的,所以它不能用1.3.1构建?这是核心问题吗?E:\GitHub\sample>jekyll服务--trace:Configurationfile:E:/GitHub/sample/_config.ymlSource:E:/GitHub/sampleDestination:E:/GitHub
String#match和Regexp#match在匹配成功时返回一个MatchData:"".match(//)#=>#//.match("")#=>#//.match(:"")#=>#但是Symbol#match返回匹配位置(如String#=~)::"".match(//)#=>0为什么Symbol#match表现不同?有用例吗? 最佳答案 我将其报告为Ruby核心中的错误:https://bugs.ruby-lang.org/issues/11991.让我们看看他们会怎么说。更新被质疑的行为似乎是一个错误。似乎从Ruby2.