捕获字母组并根据组中的数字重复它们特定次数

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

Capture letter group and repeat them certain times with the number in group

问题

我明白你的问题。你想将字符串转换为"RLFLFPAPAPA",即去掉数字并重复字母组。你的想法是使用正则表达式来捕获字母组,但是你在下面的代码中无法得到结果。你想知道如何解决这个问题,或者是否需要尝试其他方法。

在你的代码中,你已经定义了一个正则表达式(\d)\((\w+)\),用于匹配数字和括号中的字母组。要解决这个问题,你可以使用FindAllStringSubmatch函数来找到所有匹配的子字符串,并将其重复。

下面是修改后的代码:

package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

func main() {
	fmt.Println(move("R2(LF)3(PA)"))
}

func move(s string) string {
	rgx := regexp.MustCompile(`(\d)\((\w+)\)`)
	matches := rgx.FindAllStringSubmatch(s, -1)

	for _, match := range matches {
		count, _ := strconv.Atoi(match[1])
		repeated := strings.Repeat(match[2], count)
		s = strings.Replace(s, match[0], repeated, 1)
	}

	return s
}

这样,你就可以得到期望的结果"RLFLFPAPAPA"。希望能对你有所帮助!

英文:

I have string like: "R2(LF)3(PA)", and want to convert it to RLFLFPAPAPA (get rid of number and repeact the group of letters)

The idea come out is using regexp to capture the group, but I am stuck to get the result with code below, how can I solve that? Or I need to try other methods?

package main

import (
	"fmt"
	"regexp"
)

func main() {
	fmt.Println(move("R2(LF)3(PA)"))
}

func move(s string) string {

	rgx := regexp.MustCompile(`(\d)\((\w+)\)`)

	// code need here


	return s
}

答案1

得分: 2

似乎Go没有一个带有回调函数的替换函数(这对我们来说是最实用的情况)。但我找到了这个实现方法

所以思路是将包含数字的第一个组转换为整数值。然后我们可以重复第二个组中的字母这个数字次数:

package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

func main() {
	fmt.Println(move("R2(LF)3(PA)"))
}

func ReplaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
	result := ""
	lastIndex := 0
	for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
		groups := []string{}
		for i := 0; i < len(v); i += 2 {
			groups = append(groups, str[v[i]:v[i+1]])
		}
		result += str[lastIndex:v[0]] + repl(groups)
		lastIndex = v[1]
	}
	return result + str[lastIndex:]
}

func move(s string) string {
	rgx := regexp.MustCompile(`(\d)\((\w+)\)`)
	return ReplaceAllStringSubmatchFunc(rgx, s, func(groups []string) string {
		// 将第一个组中的数字转换为整数值。
		nbrTimes, err := strconv.Atoi(groups[1])
		if err != nil {
			// 处理错误(如果数字很长可能会发生错误)。
		}
		// 返回第二个组中的字母重复n次。
		return strings.Repeat(groups[2], nbrTimes)
	})
}

你可以在这里在线运行它:https://go.dev/play/p/FKNFJSc_tdS

英文:

It seems that Go doesn't have a replace function with a callback function (which is the most praticle case for us here). But I found this implementation to do it.

So the idea is to convert the first group containing a string with the number to an integer value. Then we can repeat the group 2 containing the letters this number of times:

package main

import (
	&quot;fmt&quot;
	&quot;regexp&quot;
	&quot;strconv&quot;
	&quot;strings&quot;
)

func main() {
	fmt.Println(move(&quot;R2(LF)3(PA)&quot;))
}

func ReplaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string {
	result := &quot;&quot;
	lastIndex := 0
	for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) {
		groups := []string{}
		for i := 0; i &lt; len(v); i += 2 {
			groups = append(groups, str[v[i]:v[i+1]])
		}
		result += str[lastIndex:v[0]] + repl(groups)
		lastIndex = v[1]
	}
	return result + str[lastIndex:]
}

func move(s string) string {
	rgx := regexp.MustCompile(`(\d)\((\w+)\)`)
	return ReplaceAllStringSubmatchFunc(rgx, s, func(groups []string) string {
		// Convert the first group with the digits to an integer value.
		nbrTimes, err := strconv.Atoi(groups[1])
		if err != nil {
			// Handle error (could happen if very long number).
		}
		// Return the group 2 with the letters repeated n times.
		return strings.Repeat(groups[2], nbrTimes)
	})
}

You can run it online here: https://go.dev/play/p/FKNFJSc_tdS

huangapple
  • 本文由 发表于 2022年9月26日 17:03:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/73851836.html
匿名

发表评论

匿名网友

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

确定