匹配花括号内内容的正则表达式是:\{([^{}]+)\}

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

Regex to match content inside curly braces

问题

我正在尝试创建一个正则表达式,以提取花括号之间的任何单词(字母数字),如下面的示例所示:

Hi {{ name }}, your full name is {{ concat first_name last_name }}

条件如下:

  1. 如果花括号内的内容只包含连续的字母数字,那么它是一个变量,应该被提取出来。
  2. 如果花括号内的内容包含多个由空格分隔的字母数字,那么第一个出现的是函数名,应该被忽略,但是剩下的参数(函数参数)应该被提取出来。
  3. 每个函数参数由空格分隔。
  4. 每个变量名可以包含多个单词,但是变量名中的每个单词应该使用分隔符连接,例如:first_name。
  5. 函数参数可以有一个或多个参数,每个参数都应该匹配。

所以第一个示例的结果应该是:

name, first_name, last_name.

这是我尝试的正则表达式:\{\s*\{\s*([^\}\/\s]+)\s*\}\s*\}

但它只涵盖了第一种情况。

另一个示例:

"Key": "price_change_manager.msg2 {{ message }}"
"value": "{{  username }} plan to {{formatCurrence new_price currency old_price }}"

应该匹配:message, username, new_price, currency, old_price.

英文:

I'm trying to make a regex to extract any word (alphanumeric) between curly brackets as in the example bellow:

> Hi {{ name }}, your full name is {{ concat first_name last_name }}

The conditions are:

  1. if the content inside contains only a sequential alpha_numeric, that means it is a variable and should be extracted.
  2. if the content inside contains more than one alpha_numeric separated by space, that means the first occurrence is a function name and should be ignored, but the remaining arguments (function arguments) should be extracted.
  3. each function argument is separated by space.
  4. each variable name can contain more than one word, but each word in the variable name should be connected using a separator, e.g: first_name
  5. the function arguments can have one or many arguments and each argument should be matched.

So the result for the first example should be:

name, first_name, last_name.

This is what I tried: \{\s*\{\s*([^\}\/\s]+)\s*\}\s*\}

But it only covers the first scenario.

Another example:

"Key": "price_change_manager.msg2 {{ message }}"
value": "{{  username }} plan to {{formatCurrence new_price currency old_price }}"   

Should match: message, username, new_price, currency, old_price.

答案1

得分: 1

一个不是特别过度设计的正则表达式,带有一些条件语句,可以完成工作,例如:

re := regexp.MustCompile(`\{\{ *([a-zA-Z_]+|[a-zA-Z_]+(( +[a-zA-Z_]+)+)) *\}\}`)
matches := re.FindAllStringSubmatch("{{  username }} plan to {{formatCurrence new_price currency old_price }}", -1)

这将得到一个类似的切片:

[["{{  username }}" "username" "" ""] ["{{formatCurrence new_price currency old_price }}" "formatCurrence new_price currency old_price" " new_price currency old_price" " old_price"]]

因此,你可以像这样处理它:

findings := []string{}
for _, m := range matches {
  if m[2] == "" {
    // 当第三个元素为空时,它是一个单个匹配,在第二个元素中
    findings = append(findings, m[1])
  } else {
    // 否则,它是一个多个匹配,在第三个元素中的一个字符串
    // 分割它,然后将它们附加到结果中
    findings = append(findings, strings.Split(strings.Trim(m[2], " "), " ")...)
  }
}
// 你的结果在findings中
英文:

A not particularly overengineered regexp with some ifs does do job, like:

re := regexp.MustCompile(`\{\{ *([a-zA-Z_]+|[a-zA-Z_]+(( +[a-zA-Z_]+)+)) *\}\}`)
matches := re.FindAllStringSubmatch("{{  username }} plan to {{formatCurrence new_price currency old_price }}", -1)

This will result a slice like:

[["{{  username }}" "username" "" ""] ["{{formatCurrence new_price currency old_price }}" "formatCurrence new_price currency old_price" " new_price currency old_price" " old_price"]]

So you can process it like:

  findings := []string{}
  for _, m := range matches {
    if m[2] == "" {
      // When the 3rd element is empty then it's a single match, in the 2nd element
      findings = append(findings, m[1])
    } else {
      // Otherwise it's multi match, in one string in the 3rd element
      // Split it and then append them
      findings = append(findings, strings.Split(strings.Trim(m[2], " "), " ")...)
    }
  }
  // Your result is in findings

huangapple
  • 本文由 发表于 2022年11月29日 23:04:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/74616092.html
匿名

发表评论

匿名网友

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

确定