【问题标题】:Matching groups of things, separated by specific token匹配的事物组,由特定的标记分隔
【发布时间】:2021-03-27 23:02:17
【问题描述】:

所以,这就是我正在尝试做的事情,尽管我已经为此苦苦挣扎了一段时间。

假设我们有这个输入:

{{something|a}} text text {{another|one|with|more|items}}

我想要达到的目标:

[
    ["something", "a"],
    ["another", "one", "with", "more", "items"]
]

简单的方法是这样的:

"{{something|a}} text text {{another|one|with|more|items}}".scan(/([^\|\{\}]+)/)

但这会产生 - 完全可以预见 - 所有结果都在一个数组中(另请注意,我不希望结果中有“文本文本”,只需要花括号中的项目):

[["something"], ["a"], [" text text "], ["another"], ["one"], ["with"], ["more"], ["items"]] 

然后我尝试像 (see script here) 那样做:

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

但我一定是做错了什么。

任何帮助将不胜感激! :)

【问题讨论】:

  • 您无法在 Ruby 中获取某个组的所有捕获值。捕获的数量总是与模式中的捕获组一样多。所以,.scan(/{{(.*?)}}/).flatten.map{ |x| x.split("|") } seems to work 在这里。
  • @WiktorStribiżew 如此简单直接。我应该有那样接近它...非常感谢! (只需将其发布为答案,我会很乐意接受它:))

标签: regex ruby


【解决方案1】:

您无法在 Ruby 中获取所有捕获的 repeated capturing group 值。 捕获的数量总是与模式中的捕获组一样多。

因此,您需要输入更多代码才能获得预期的输出:

s = '{{something|a}} text text {{another|one|with|more|items}}'
p s.scan(/{{(.*?)}}/).flatten.map{ |x| x.split("|") }
# => [["something", "a"], ["another", "one", "with", "more", "items"]]

请参阅Ruby demo

注意{{(.*?)}} 模式匹配{{ 子字符串,然后是除换行符之外的任何零个或多个字符,然后是}},然后.flatten 将结果转换为字符串数组,并且然后在map 调用中的x.split("|") 将找到的捕获组值与| 分开。

注意:如果{{}} 之间可以有换行符,请添加/m 修饰符/{{(.*?)}}/m。或者,展开模式以提高效率:/{{[^}]*(?:}(?!})[^}]*)*}}/(请参阅Rubular demo)。

【讨论】:

  • 再次感谢!很好的答案:)
  • @Dr.Kameleon 感谢提出了一个非常好的和明确的问题。如果你想知道我所说的“展开模式”是什么意思,请参考Unroll Loop, when to use
猜你喜欢
  • 1970-01-01
  • 2021-05-26
  • 2022-11-03
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多