在Golang中删除包含特定子字符串的行。

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

Remove lines containing certain substring in Golang

问题

在Go语言中,你可以使用以下代码来删除以特定子字符串开头的行:

package main

import (
	"bytes"
	"fmt"
)

func main() {
	lines := []byte(`line1
line2
substring1
line3
substring2
line4`)

	substring := []byte("substring")

	result := bytes.Split(lines, []byte("\n"))
	var filtered [][]byte

	for _, line := range result {
		if !bytes.HasPrefix(line, substring) {
			filtered = append(filtered, line)
		}
	}

	output := bytes.Join(filtered, []byte("\n"))
	fmt.Println(string(output))
}

在上面的代码中,我们首先将输入的字符串转换为[]byte类型的变量lines。然后,我们使用bytes.Split函数将其拆分为行的切片。接下来,我们使用循环遍历每一行,并使用bytes.HasPrefix函数检查是否以指定的子字符串开头。如果不是以指定的子字符串开头,我们将该行添加到filtered切片中。最后,我们使用bytes.Join函数将过滤后的行重新连接为一个字符串,并打印输出。

请注意,上述代码仅适用于以换行符分隔的行。如果你的输入使用其他行分隔符,请相应地修改代码中的[]byte("\n")部分。

英文:

How to remove lines that started with certain substring in []byte, in Ruby usually I do something like this:

lines = lines.split("\n").reject{|r| r.include? 'substring'}.join("\n")

How to do this on Go?

答案1

得分: 13

你可以使用正则表达式来模拟这个操作:

re := regexp.MustCompile(`(?m)[\r\n]+^.*substring.*$`)
res := re.ReplaceAllString(s, "")

OP Kokizzu 使用了 "(?m)^.*" +substr+ ".*$[\r\n]+"

参考这个示例

func main() {
    s := `aaaaa
bbbb
cc substring ddd
eeee
ffff`
    re := regexp.MustCompile(`(?m)[\r\n]+^.*substring.*$`)
    res := re.ReplaceAllString(s, "")
    fmt.Println(res)
}

输出结果:

aaaaa
bbbb
eeee
ffff

请注意使用了正则表达式标志 (?m)

多行模式:^$ 匹配行的开头和结尾,而不仅仅是文本的开头和结尾(默认为 false)

英文:

You could emulate that with regexp:

re := regexp.MustCompile("(?m)[\r\n]+^.*substring.*$")
res := re.ReplaceAllString(s, "")

(The OP Kokizzu went with "(?m)^.*" +substr+ ".*$[\r\n]+")

See this example

func main() {
	s := `aaaaa
bbbb
cc substring ddd
eeee
ffff`
	re := regexp.MustCompile("(?m)[\r\n]+^.*substring.*$")
	res := re.ReplaceAllString(s, "")
	fmt.Println(res)
}

output:

aaaaa
bbbb
eeee
ffff

Note the use of regexp flag (?m):

> multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)

答案2

得分: 2

我相信在这个任务中使用bytes包比使用regexp更好。

package main

import (
	"fmt"
	"bytes"
)

func main() {
	myString := []byte("aaaa\nsubstring\nbbbb")
	lines := bytes.Replace(myString, []byte("substring\n"), []byte(""), 1)
	
	fmt.Println(string(lines)) // 将字节转换为字符串以进行打印
}

输出:

aaaa
bbbb

在这里尝试一下。

英文:

I believe using the bytes package for this task is better than using regexp.

package main

import (
	"fmt"
	"bytes"
)

func main() {
	myString := []byte("aaaa\nsubstring\nbbbb")
	lines := bytes.Replace(myString, []byte("substring\n"), []byte(""), 1)
	
	fmt.Println(string(lines)) // Convert the bytes to string for printing
}

Output:

aaaa
bbbb

Try it here.

答案3

得分: 2

问题标题的意思与原始问题的措辞方式不同。作为接受的解决方案提供的正则表达式不能解决我要删除整行的用例,就像问题标题所示。

为了在Go中删除包含特定子字符串的行(问题的标题),你可以实现与Kokizzu最初编写的Ruby代码非常相似的Go代码。

func removeLinesContainingAny(input string, toRemove []string) string {
  if !strings.HasSuffix(input, "\n") {
    input += "\n"
  }

  lines := strings.Split(input, "\n")

  for i, line := range lines {
    for _, rm := range toRemove {
      if strings.Contains(line, rm) {
        lines = append(lines[:i], lines[i+1:]...)
      }
    }
  }

  input = strings.Join(lines, "\n")
  input = strings.TrimSpace(input)
  input += "\n"

  return input
}

在这里查看测试用例:https://go.dev/play/p/K-biYIO1kjk

特别要注意确保输入字符串末尾有一个换行符,否则在某些情况下会出现slice bounds out of range的恐慌。

英文:

The question title does not have the same meaning as the way the original question was worded. The Regex provided as the accepted solution did not solve for the use case I had of removing a whole line when finding a matching substring, like the question title indicates.

In order to remove lines that contain certain substrings in Go (title of the question), you could implement something in Go very similar to the Ruby code that Kokizzu wrote initially.

func removeLinesContainingAny(input string, toRemove []string) string {
  if !strings.HasSuffix(input, "\n") {
	input += "\n"
  }

  lines := strings.Split(input, "\n")

  for i, line := range lines {
	for _, rm := range toRemove {
	  if strings.Contains(line, rm) {
	    lines = append(lines[:i], lines[i+1:]...)
	  }
	}
  }

  input = strings.Join(lines, "\n")
  input = strings.TrimSpace(input)
  input += "\n"

  return input
}

See test cases here: https://go.dev/play/p/K-biYIO1kjk

In particular, you need to ensure there is a new line at the end of the input string, otherwise you will get a panic for slice bounds out of range in certain cases.

答案4

得分: 0

这个已批准的解决方案在需要删除顶部行时将无法工作:

func main() {
    s := `aaaaa substring
bbbb
cc substring ddd
eeee
ffff`
    re := regexp.MustCompile(`(?m)[\r\n]+^.*substring.*$`)
    res := re.ReplaceAllString(s, "")
    fmt.Println(res)
}
英文:

This approved solution will not work when you need to remove the top line :

func main() {
    s := `aaaaa substring
bbbb
cc substring ddd
eeee
ffff`
    re := regexp.MustCompile("(?m)[\r\n]+^.*substring.*$")`enter code here`
    res := re.ReplaceAllString(s, "")
    fmt.Println(res)
}

huangapple
  • 本文由 发表于 2014年12月11日 15:21:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/27417364.html
匿名

发表评论

匿名网友

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

确定