替换字符串中每个第n个字符的实例。

huangapple go评论162阅读模式
英文:

Replace every nth instance of character in string

问题

我对Go语言还有点陌生,但我正在尝试用逗号替换每个字符串的第n个实例。例如,我的数据的一部分如下所示:

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,

我想用'\n'替换每个第6个逗号,使其看起来像这样:

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769"
"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506"
"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991"

我查看了regexp包,它似乎只是一个查找器。strings包有一个替换函数,但我不知道如何使用它来替换特定的索引。我也不知道如何在不逐个字符遍历整个字符串的情况下找到特定的索引。我想知道是否有一个比我编写一个辅助函数更优雅的正则表达式解决方案。
字符串是不可变的,所以我不能直接在原地编辑它们。

编辑:将字符串转换为[]bytes。这样我就可以原地编辑字符串了。然后剩下的就是一个相当简单的for循环,其中dat是数据。

英文:

I'm a bit new to Go, but I'm trying to replace every nth instance of my string with a comma. So for example, a part of my data looks as follows:

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,

I want to replace every 6th comma with a '\n' so it looks like

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769"
"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506"
"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991"

I've looked at the regexp package and that just seems to be a finder. The strings package does have a replace but I don't know how to use it to replace specific indices. I also don't know how to find specific indices without going through the entire string character by character. I was wondering if there is a regEx solution that is more elegant than me writing a helper function.
Strings are immutable so I'm not able to edit them in place.

EDIT: Cast the string into []bytes. This allows me to edit the string in place. Then the rest is a fairly simple for loop, where dat is the data.

答案1

得分: 1

如果这是你的输入,你应该将,"字符串替换为\n"。你可以使用strings.Replace()来实现。这将留下一个末尾的逗号,你可以用切片操作来移除它。

解决方案:

in := `"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,`
out := strings.Replace(in, `,"`, `\n"`, -1)
out = out[:len(out)-1]
fmt.Println(out)

输出结果为(在Go Playground上尝试):

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769
"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506
"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991
英文:

If that is your input, you should replace ," strings with \n".You may use strings.Replace() for this. This will leave a last, trailing comma which you can remove with a slicing.

Solution:

in := `"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,`
out := strings.Replace(in, ",\"", "\n\"", -1)
out = out[:len(out)-1]
fmt.Println(out)

Output is (try it on the Go Playground):

"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769
"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506
"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991

答案2

得分: 1

如果你想要灵活的话。

package main

import (
	"fmt"
	"strings"
)

func main() {
	input := `"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,`
	var result []string

	for len(input) > 0 {
		token := strings.SplitN(input, ",", 7)
		s := strings.Join(token[0:6], ",")
		result = append(result, s)
		input = input[len(s):]
		input = strings.Trim(input, ",")
	}
	fmt.Println(result)
}

链接:https://play.golang.org/p/mm63Hx24ne

英文:

If you want flexible.

package main

import (
	"fmt"
	"strings"
)

func main() {
	input := `"2017-06-01T09:15:00+0530",1634.05,1635.95,1632.25,1632.25,769,"2017-06-01T09:16:00+0530",1632.25,1634.9,1631.65,1633.5,506,"2017-06-01T09:17:00+0530",1633.5,1639.95,1633.5,1638.4,991,`
	var result []string

	for len(input) > 0 {
		token := strings.SplitN(input, ",", 7)
		s := strings.Join(token[0:6], ",")
		result = append(result, s)
		input = input[len(s):]
		input = strings.Trim(input, ",")
	}
	fmt.Println(result)
}

https://play.golang.org/p/mm63Hx24ne

答案3

得分: 1

所以我找出了我做错的地方。我最初将数据作为一个string,但是如果我将其转换为byte[],那么我就可以直接在原地更新它。

这使我能够使用下面的简单for循环解决问题,而无需依赖于除了第n个字符实例之外的任何其他指标。

for i := 0; i < len(dat); i++ {
    if dat[i] == ',' {
        count += 1
    }
    if count%6 == 0 && dat[i] == ',' {
        dat[i] = '\n'
        count = 0
    }
}
英文:

So I figured out what I was doing wrong. I initially had the data as a string, but if I cast it to a byte[] then I can update it in place.

This allowed me to use a simple for loop below to solve the issue without relying on any other metric other than nth character instance

for i := 0; i &lt; len(dat); i++ {
    if dat[i] == &#39;,&#39; {
        count += 1
    }
    if count%6 == 0 &amp;&amp; dat[i] == &#39;,&#39; {
        dat[i] = &#39;\n&#39;
        count = 0
    }

huangapple
  • 本文由 发表于 2017年6月28日 16:12:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/44797043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定