首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从字符串中解析短代码

从字符串中解析短代码
EN

Code Review用户
提问于 2023-01-06 17:31:03
回答 1查看 64关注 0票数 0

我编写了这个短代码解析,它在O(N^2)中运行。有更好的方法来优化这个吗?

代码语言:javascript
复制
  package shortcodes

  import (
          "regexp"
          "strings"
  )

  var (
          shortcodesRegex = regexp.MustCompile(`\[\S+(?:\s+[^="]+(|="[^"\]\s]+"))+\]`)
  )

  func Parse(content string) []map[string]string {
          results := make([]map[string]string, 0)
          indexes := shortcodesRegex.FindAllIndex([]byte(content), -1)

          for _, matches := range indexes {
                  result := make(map[string]string)
                  shortcode := string(content[matches[0]+1 : matches[1]-1])
                  parts := strings.Fields(shortcode)

                  for i, part := range parts {
                          if i == 0 {
                                  result["id"] = part
                                  continue
                          }

                          pair := strings.Split(part, "=")
                          if len(pair) > 1 {
                                  result[pair[0]] = pair[1][1 : len(pair[1])-1]
                          } else {
                                  result[pair[0]] = ""
                          }
                  }

                  results = append(results, result)
          }

          return results
  }

这里是我编写的测试用例之一。

代码语言:javascript
复制
                  {
                          name: "basic",
                          args: args{`First shortcode is [fraction num="1" denom="2"] and the second is [square-root content="456"] which we will pass into a function which will return these IDs and all their values in a map`},
                          want: []map[string]string{
                                  {
                                          "id":    "fraction",
                                          "num":   "1",
                                          "denom": "2",
                                  },
                                  {
                                          "id":      "square-root",
                                          "content": "456",
                                  },
                          },
                  },
EN

回答 1

Code Review用户

回答已采纳

发布于 2023-01-06 19:11:40

谢谢你的单元测试!它们是无价的;它们确实帮助我理解了你正在处理的问题。

我在读这个

代码语言:javascript
复制
\[\S+(?:\s+[^="]+(|="[^"\]\s]+"))+\]

我对此并不满意,原因有几点。

应该有一个评论来说明我们寻求匹配的文本类型。( 短信参考是没有帮助的。)

匹配任务看起来相当简单,但是这个表达式相对不透明。我不认为这是一种向合作者传达技术想法的好方法。

?:非捕获组看起来很奇怪,并且有可能在regex引擎中触发过多的回溯,这可能就是您的二次运行时间的来源。

在代码的下面,我们发现字符串被解析了。

  • 使用正则表达式
  • 使用空白分隔字段
  • 使用=-delimited拆分

可以肯定的是,一只带着捕获群的大政王就能在一次突然袭击中挑出我们需要的东西?

如果有一个有效的短代码规范,请引用它的URL。正如所写的,这段代码愿意接受大量的$%^&*标点符号,我怀疑这不是预期的业务用例的一部分。

考虑使用看起来更像这样的regex:

代码语言:javascript
复制
^\[([\w-]+)(\s+\w+="\d+")+\]$

或者使用细粒度捕获组:

代码语言:javascript
复制
\[([\w-]+)(\s+(\w+)="(\d+)")+\]

如果[a b-c="7"]是有效输入,那么将\w+转换为[\w-]+

字段和拆分逻辑足够普通,带有+/- 1索引偏移,可以去掉标点符号。逻辑与regex紧密绑定,正则表达式验证是否找到了正确的标点符号。我会更高兴地看到一些逻辑被推入正则表达式,将其保存在一个地方,并使维护人员更有可能正确地协调更改。使用细粒度捕获组似乎是实现这一目标的自然方法。

由于“过长的运行时间”一直是此代码在过去面临的挑战,请添加一个单元测试来解决这个问题,并验证没有回归。请添加代码,提供“非常长”的输入字符串进行分析,并记下经过的壁挂钟时间。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/282411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档