jjzjj

string - Go 的 LeftStr、RightStr、SubStr

coder 2024-07-06 原文

我相信没有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)的几个级别。

  1. 只需使用 n 个字节。 这可能会在一个 rune 中间拆分,但是 O(1),非常简单,并且在许多情况下您知道输入仅包含单字节 rune 。 例如。 str[:n].

  2. 在 n 个 rune 后拆分。 这可能会在一个字符的中间 split 。这可以很容易地完成,但代价是仅使用 string([]rune(str)[:n]) 进行复制和转换。 您可以使用 unicode/utf8 避免转换和复制包的DecodeRuneInString(和DecodeLastRuneInString)函数依次获取前n个 rune 的长度,然后返回str[:sum]( O(n),没有分配)。

  3. 在第 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 - Go 的 LeftStr、RightStr、SubStr的更多相关文章

  1. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  2. ruby - 从 String#split 返回的零长度字符串 - 2

    在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"

  3. ruby - json 没有将 String 隐式转换为 Integer (TypeError) - 2

    玩转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.

  4. ruby - 类型错误 : can't convert String into Integer - 2

    我有代码: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`[]'

  5. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  6. ruby - 为什么 String::sub!() 会更改 Ruby 中克隆对象的原始对象? - 2

    我的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'这样

  7. ruby - 重构 Ruby : Converting string array to int array - 2

    我正在重构一个西洋跳棋程序,我正在尝试将玩家移动请求(例如以“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

  8. ruby - "string literal in condition"是什么意思? - 2

    每当我尝试运行该程序时,都会弹出一条错误消息“条件字符串文字(第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

  9. ruby - 杰基尔服务错误 : no implicit conversion of nil into String - 2

    我用这个错误搜索了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

  10. ruby - 为什么 `Symbol#match` 的行为与 `String#match` 和 `Regexp#match` 不同? - 2

    String#match和Regexp#match在匹配成功时返回一个MatchData:"".match(//)#=>#//.match("")#=>#//.match(:"")#=>#但是Symbol#match返回匹配位置(如String#=~)::"".match(//)#=>0为什么Symbol#match表现不同?有用例吗? 最佳答案 我将其报告为Ruby核心中的错误:https://bugs.ruby-lang.org/issues/11991.让我们看看他们会怎么说。更新被质疑的行为似乎是一个错误。似乎从Ruby2.

随机推荐