如何在Golang中的正则表达式中的第一个匹配项之前插入子字符串?

如何在Golang中的正则表达式中的第一个匹配项之前插入子字符串?

问题描述:

I have a regex as following (ORDER\s+BY)|(LIMIT)|$. I want to insert a substring before the first match of the regex. I am looking for a pure regexp solution in Golang not finding the index and then adding a substring. Since Golang only has regexp.ReplaceAll func which replaces all the matches, not the first one.

exp := regexp.MustCompile(`(ORDER\s+BY)|(LIMIT)|$`)
fmt.Println(exp.ReplaceAllString(str, "..."))

Example

Input: abcd ORDER BY LIMIT substring=GROUP BY

Expected output: abcd GROUP BY ORDER BY LIMIT

Input: abcd LIMIT

Expected output: abcd GROUP BY LIMIT

我有一个正则表达式,如下所示(ORDER \ s + BY)|(LIMIT)| $ 代码>。 我想在正则表达式的第一个匹配项之前插入一个子字符串。 我在Golang中寻找纯正则表达式解决方案,但没有找到索引,然后添加了子字符串。 由于Golang仅具有regexp.ReplaceAll函数,它将替换所有匹配项,而不是第一个匹配项。 p>

  exp:= regexp.MustCompile(`(ORDER \ s + BY)|(  LIMIT)| $`)
fmt.Println(exp.ReplaceAllString(str,“ ...”))
  code>  pre> 
 
 

示例 p>

输入: abcd ORDER BY LIMIT code> substring = GROUP BY code> p>

预期输出: abcd GROUP BY ORDER BY LIMIT code> p>

输入: abcd LIMIT code> p>

预期的输出: abcd GROUP BY LIMIT code > p> div>

You may use

str := "abcd ORDER BY LIMIT"
exp := regexp.MustCompile(`^(.*?)(ORDER\s+BY|LIMIT|$)`)
fmt.Println(exp.ReplaceAllString(str, "${1}GROUP BY ${2}"))

If there can be line breaks before the pattern use (?s) in front: (?s)^(.*?)(ORDER\s+BY|LIMIT|$).

See the Go demo and the regex graph:

enter image description here

Details

  • ^ - start of string
  • (.*?) - Group 1 (${1}): any 0+ chars, as few as possible
  • (ORDER\s+BY|LIMIT|$) - Group 2 (${2}): any of the three alternatives, whichever comes first:
    • ORDER\s+BY - ORDER, 1+ whitespaces, BY
    • LIMIT - a LIMIT substring
    • $ - end of string.

My guess is that this expression might work here:

(ORDER\s+BY\s+LIMIT|LIMIT)$

Demo

Test

package main

import (
    "regexp"
    "fmt"
)

func main() {
    var re = regexp.MustCompile(`(?m)(ORDER\s+BY\s+LIMIT|LIMIT)$`)
    var str = `abcd ORDER BY LIMIT
abcd LIMIT`
    var substitution = "GROUP BY $1"

    fmt.Println(re.ReplaceAllString(str, substitution))
}