多行正则表达式中的ruby字符串替换

时间:2016-01-14 19:43:08

标签: ruby regex

我试图在跨越多行的ruby正则表达式中使用sting替换。我认为问题是在Free-Spacing模式下,'#'被视为评论。

首先是有更好的方法来分解长正则表达式,其次,我应该如何在Free-Spacing正则表达式中执行替换

下面的代码有两个例子。 get_module_name_a,正则表达式全部在一行上正常工作,get_module_name_b与自由间距正则表达式,其中替换最终被视为注释(我认为)。

理想情况下,我希望将线条的长度保持在80个字符以下。

代码的输出目前是

$ ruby test.rb 
testmod2
test.rb:42:in `get_module_name_b': undefined method `[]' for nil:NilClass (NoMethodError)
    from test.rb:46:in `<main>'

示例代码:

#!/usr/bin/env ruby

def loadFile
  "
mod 'testmod1',
  :git => 'git@testing.com:reaktor/testmod1.git',
  :ref => 'RELEASE_1.0.0'

mod 'testmod2',
  :git => 'git@testing.com:reaktor/myproject-testmod2.git',
  :ref => 'RELEASE_2.0.10'

mod 'testmod3',
  :git => 'git@testing.com:reaktor/testmod3.git',
  :tag => 'RELEASE_10.2.3'

  "
end

def get_module_name_a(repo_name)
  input_string = loadFile
  regex = /mod ["'](\w*)["'],\s*$\n+(\s*):git\s*=>\s*["'].*#{repo_name}.git["'],$\n+(\s*):ref\s*=>\s*['"](\w+|\w+\.\d+\.\d+)['"]$/
  result = regex.match(input_string)
  result[1]
end

def get_module_name_b(repo_name)
  input_string = loadFile
  regex = /\A
    mod ["'](\w*)["'],\s*$\n
    +(\s*):git\s*=>\s*["'].*#{repo_name}.git["'],$\n
    +(\s*):ref\s*=>\s*['"](\w+|\w+\.\d+\.\d+)['"]$
    \Z/x
  result = regex.match(input_string)
  result[1]
end

puts get_module_name_a('myproject-testmod2')
puts get_module_name_b('myproject-testmod2')

2 个答案:

答案 0 :(得分:1)

这里要提几件事:

  • 文字空间应放入[ ]正则表达式中的字符类/x(此处为mod之后的<}}
  • 您在B方法中一起$\Z
  • 注意量词,将它们放在它们应用的模式旁边
  • 你的正则表达式中的
  • \A强制在字符串的开头匹配,而第一个正则表达式没有那个限制

这是一个有效的代码:

def get_module_name_b(repo_name)
  input_string = loadFile
  regex = /mod[ ]["'](\w*)["'],\s*$\n+
    (\s*):git\s*=>\s*["'].*#{repo_name}.git["'],$\n+
    (\s*):ref\s*=>\s*['"](\w+|\w+\.\d+\.\d+)['"]
    $/x
  result = regex.match(input_string)
  result[1]
end

请参阅IDEONE demo

如果将(\w+|\w+\.\d+\.\d+)正则表达式部分更改为(\w+(?:\.\d+\.\d+)?),则可以合同并提高效率。

答案 1 :(得分:0)

Regexp.new("ab #{'c d'}", Regexp::EXTENDED)将匹配abcd

所以你可以使用

regex = Regex.new <<-REGEXP, Regexp::EXTENDED
  \A
  mod ["'](\w*)["'],\s*$\n
  +(\s*):git\s*=>\s*["'].*#{repo_name}.git["'],$\n
  +(\s*):ref\s*=>\s*['"](\w+|\w+\.\d+\.\d+)['"]$
  \Z
REGEXP

由于这使用标准字符串插值,因此以这种方式定义正则表达式与x选项没有冲突。