【问题标题】:Regular Expression to select text between curly braces, Ruby正则表达式在大括号之间选择文本,Ruby
【发布时间】:2016-05-09 22:01:04
【问题描述】:

我正在研究一种过滤和替换损坏的大括号标签(例如{{hello})的方法。我已经在 Stack 中尝试了一些正则表达式并自己尝试过。我来的关闭是使用这个正则表达式 (?=(\}(?!\})))((?<!\})\}) 选择下面示例代码块中的最后一个标签。但是它不会选择整个标签,它只是选择结束大括号}

{{hello}}
{{world}}}
{{foobar}}
{{hello}

我需要做的是选择任何缺少第二个结尾大括号的标签,例如{{hello}。谁能帮我用正则表达式来选择这种类型的标签?

【问题讨论】:

  • 也许像(?<!{){{[^{}]+}(?!}) 这样的东西会有所帮助。
  • input.gsub(/(?<!{){{[^{}]+}(?!})/, "\\0}")。还是只想从最后一个“tag”中获取“hello”字符串?
  • 你允许{{test\}}}{{this {{too}}}}吗?
  • Cary 发布了一个类似的解决方案。我的正则表达式只是确保第一个{{ 前面没有另一个{,而关闭} 后面没有}
  • 我发布了带有解释的答案。

标签: ruby regex


【解决方案1】:

过滤和替换损坏的大括号标签

如果你不嵌套东西,这个问题真的很容易解决。

试试这个:

[\{]+([^}]+)[}]+

基本上,您可以将匹配项替换为{{\1}}(或{{$1}},我忘记了Ruby 使用的是哪一个。)

只要在比赛前后连续出现{} 中的一个或多个即可。

【讨论】:

  • 嗨 Laurel,感谢您发布答案。您的解决方案也适用于我的应用程序。
【解决方案2】:

我假设给定一个字符串,其中包含以“{{”开头的子字符串,后跟一个“tag”,这是一个由“{”和“}”以外的字符组成的字符串,后跟“}”或“ }}”。我们希望返回仅后跟一个右大括号的标签。例如:

str = "Sue said {{hello}}, Bob said {{world}\nTom said {{foobar}}, Lola said {{hello}"

我们可以使用以下正则表达式:

r = /
    \{\{        # match {{
    ([^}]+)     # match one or more characters other than } in capture group 1
    \}          # match }
    (?:\z|[^}]) # match end of line or a character other than }
                # in a non-capture group        
    /x          # free-spacing regex definition mode

str.scan(r).flatten
  #=> ["world", "hello"]

正则表达式当然可以用传统方式编写:

r = /\{\{([^}]+)\}(?:\z|[^}])/

注意

str.scan(r)
  => [["world"], ["hello"]] 

因此需要flatten

请参阅String#scan 了解说明。

显然,如果

str = "{{hello}}\n{{world}\n{{foobar}}\n{{hello}"

str.scan(r).flatten
  #> ["world", "hello"]

如果

words = %w| {{hello}} {{world} {{foobar}} {{hello} |
  #=> ["{{hello}}", "{{world}", "{{foobar}}", "{{hello}"]

然后

words.select { |w| w =~ r }.map { |w| w[/[^{}]+/] } 
  => ["world", "hello"] 

【讨论】:

  • 嗨,Cary,感谢您的解决方案和雄辩的解释,效果很好。 Wiktor 的解决方案也很有效。感谢您的发表。当我获得足够的声望时,我会回来为你投票。
【解决方案3】:

我建议使用以下表达式:

/(?<!{){{[^{}]+}(?!})/

regex101 demo

该模式将匹配{{开头前面没有{的任何文本字符串,后跟除{}之外的任何1+字符和然后是}后面没有}。因此,此模式匹配完全匹配{{xxx} 结构的字符串

这是Ruby demo

"{{hello}".gsub(/(?<!{){{[^{}]+}(?!})/, "\\0}")
# => {{hello}}

模式详情

  • (?&lt;!{) - 如果{ 立即出现在当前位置的左侧,则表示匹配失败
  • {{ - 文字 {{
  • [^{}]+ - 除了 {} 之外的 1+ 个字符(要允许空值,请使用 * 而不是 +
  • } - 结束单曲}
  • (?!}) - 如果 } 出现在之前匹配的 } 之后,则匹配失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2020-02-24
    • 1970-01-01
    相关资源
    最近更新 更多