如何捕捉一个角色并重复它#34;下一场比赛?

时间:2014-11-01 20:23:50

标签: ruby regex

我有这个文字,我需要提取所有指南针(由|:|,...等表示)

X:1
T:Paddy O'Rafferty
C:Trad.
M:6/8
K:D
dff cee|def gfe|dff cee|dfe dBA|dff cee|def gfe|faf gfe|1 dfe dBA:|2 dfe dcB|]
~A3 B3|gfe fdB|AFA B2c|dfe dcB|~A3 ~B3|efe efg|faf gfe|1 dfe dcB:|2 dfe dBA|]
fAA eAA|def gfe|fAA eAA|dfe dBA|fAA eAA|def gfe|faf gfe|dfe dBA:|

现在我有以下正则表达式:

/([\|\[].+?[\|\]])/m

每个其他罗盘都有效,因为[\|\]]此标记“消耗”了角色。

我想以这种方式捕捉指南针:

|def gfe|
|dff cee|
|dfe dBA|
|dff cee|
|def gfe|
|faf gfe|
|1 dfe dBA:|
|2 dfe dcB|]

3 个答案:

答案 0 :(得分:0)

使用String#scan返回所有匹配的Array

例如:

 text = 'your long text up there'
 text.scan(/([\|\[].+?[\|\]])/m)

以上回报:

[["|def gfe|"], ["|dfe dBA|"], ["|def gfe|"], ["|1 dfe dBA:|"], ["|]\n~A3 B3|"], ]...], [...]]

希望这有帮助

答案 1 :(得分:0)

您可以通过以下几种方式实现这一目标。

#1在每一行上使用String#split,然后修复该行的结尾。

def split_em(str)
  arr = str.split(?|).map { |s| "|#{s}|" }
  arr[-1] << (arr.pop).tr(?|,'') unless str[-1] == ?|
  arr
end

split_em("dff cee|def gfe|dff cee|dfe dBA|dff cee|def gfe|faf gfe|1 dfe dBA:|2 dfe dcB|]")
  #=> ["|dff cee|", "|def gfe|", "|dff cee|", "|dfe dBA|", "|dff cee|",
  #    "|def gfe|", "|faf gfe|", "|1 dfe dBA:|", "|2 dfe dcB|]"]
split_em("~A3 B3|gfe fdB|AFA B2c|dfe dcB|~A3 ~B3|efe efg|faf gfe|1 dfe dcB:|2 dfe dBA|]")
  #=> ["|~A3 B3|", "|gfe fdB|", "|AFA B2c|", "|dfe dcB|", "|~A3 ~B3|",
  #    "|efe efg|", "|faf gfe|", "|1 dfe dcB:|", "|2 dfe dBA|]"]
split_em("fAA eAA|def gfe|fAA eAA|dfe dBA|fAA eAA|def gfe|faf gfe|dfe dBA:|")
  #=> ["|fAA eAA|", "|def gfe|", "|fAA eAA|", "|dfe dBA|",
  #    "|fAA eAA|", "|def gfe|", "|faf gfe|", "|dfe dBA:|"]

#2将正则表达式应用于每一行以创建数组,然后修改数组的每个元素

def split_em(str)
  str.scan(/(?<=^|\|).+?\|(?:[^|]*?$)?/).map { |s| "|#{s}" }
end
  • (?<=^|\|)是一个积极的lookbehind,匹配行的开头或|
  • .+?非贪婪地抓取一个或多个字符(以便不会吞噬其余部分),然后匹配|,然后匹配({1}}为?非捕获组),除了|之外的零个字符,直到行尾。
  • map|添加到数组中每个字符串的开头。

开放挑战以改进正则表达式:

  • 而不是将其应用于每一行,将其应用于包含所有行的字符串,返回包含每行的字符串数组的数组。
  • 消除map

答案 2 :(得分:0)

我从评论和示例中注意到,您不想在一行的开头捕捉罗盘,也许是因为左边没有|,结果总是有左侧只有|,右侧只有[|, ||, |:, :|, ..., etc 尝试这种模式:

(?<=[\]:|])([^|\r\n]+\|[:\]]?)

问题是,您无法通过同一个捕获组捕获相同的字符两次,因此您必须放弃在左侧捕获|并稍后使用您的脚本语言添加它。

(?<=[\]:|])     # a look-behind for any of "]:|"
(               # capture gourp 1
    [^|\r\n]+   # anything that is not one of "|\r\n"
    \|          # followed by "|"
    [:\]]?      # followed by and optional one of ":]"
)               # end of capture group 1  

Demo
希望它有所帮助