【问题标题】:Split a Ruby string by colon (except inside parenthesis) using regex使用正则表达式通过冒号(括号内除外)拆分 Ruby 字符串
【发布时间】:2017-02-28 07:44:02
【问题描述】:

我想用冒号分割一个字符串。

这是一个输入示例:

str = "one[two:[three::four][five::six]]:seven:eight[nine:ten]"

这是一个输出示例:

array = ["one[two:[three::four][five::six]]", "seven", "eight[nine:ten]"]

目的是理解regex代表括号外的冒号和嵌套的括号

但是有一些限制:

  • 正则表达式的模板必须是这样的:^(.+)<colon_regex>(.*)<colon_regex>(.*)$
  • 匹配项必须是唯一的,包含三个组。

你能给我一个建议吗?

【问题讨论】:

  • 那么,第一个约束意味着one:two:three:four 应该不匹配,对吧?
  • 谢谢卡里。刚刚编辑。
  • Wiktor 这个输入 str = "one:two:three:four" 必须产生这个输出数组 = ["one", "two", "three", "four"] 但使用这个模板 ^ (.+)(.*)(.*)(.*)$
  • 你不能在获得所有匹配项后使用特殊检查吗?请参阅ideone.com/xOPItz,其中使用chunk_countvar 实现该约束。
  • 没有。我不能。我需要单行正则表达式。 ......或更好......单行正则表达式的傀儡需求。

标签: ruby regex


【解决方案1】:

你可以使用一个非常简单的正则表达式:

SUB_CHAR = 0.chr
  #=> "\x00"
r = /#{SUB_CHAR}/
  #=> /\x00/

用于s.split(r)

当然有一个问题:您必须修改传递给 Puppet 的字符串(以及上面的正则表达式)。

str = "one[two:[three::four][five::six]]:seven:eight[nine:ten]"

count = 0

idx = str.size.times.with_object([]) do |i,a|
  case str[i]
  when '[' then count += 1
  when ']' then count -= 1
  when ':' then a << i if count.zero?
  end
end
  #=> [33, 39]

s = str.dup
  #=> "one[two:[three::four][five::six]]:seven:eight[nine:ten]"
idx.each { |i| s[i] = SUB_CHAR }
s #=> "one[two:[three::four][five::six]]\u0000seven\u0000eight[nine:ten]"
s.split(r)
  #=> ["one[two:[three::four][five::six]]", "seven", "eight[nine:ten]"] 

【讨论】:

  • 谢谢。不幸的是,我需要正则表达式解决方案,因为我将在 Puppet 模块(仅接受正则表达式)的 title_patterns 方法中使用 ruby​​ 正则表达式。
  • 我修改了我的答案,为你提供我认为你需要的东西,虽然有点笨拙,但有时你会做你必须做的事情。
  • 我不知道 Puppet(或一般的 Rails),所以我假设字符串和正则表达式都传递给 Puppet 可能是不正确的。
  • Puppet 是一个软件配置管理器,它使用 Ruby 来完成一些功能。但在某些情况下,它会施加限制。
  • BnG,你会将字符串和正则表达式都传递给 Puppet 吗?如果是这样,我会提出工作吗?
【解决方案2】:

适配this嵌套括号正则表达式,可以这样做:

txt="one[two:[three::four][five::six]]:seven:eight[nine:ten]" 
pat=Regexp.new('((?>[^:\[]+|(\[(?>[^\[\]]+|\g<-1>)*\]))+)')
puts txt.scan(pat).map &:first
one[two:[three::four][five::six]]
seven
eight[nine:ten]

【讨论】:

  • ...嗯...好的。有用。但我不能调用 map 方法(Puppet title_patterns 方法施加的限制)并且它解析任何刺痛。相反,您的输入应该由正则表达式解析,例如 ^(.+)(.*)(.*)$
  • @BnG:没有递归,纯粹使用正则表达式是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
相关资源
最近更新 更多