使用ARGV []参数向量在Ruby中传递正则表达式

时间:2016-02-05 15:58:15

标签: ruby regex argv

我正在尝试将gsubsub用于通过终端传递给ARGV[]的正则表达式。

在终端中查询:$ruby script.rb input.json "\[\{\"src\"\:\"

输入文件前2行:

[{
    "src":"http://something.com",
    "label":"FOO.jpg","name":"FOO",
    "srcName":"FOO.jpg"
}]
[{
    "src":"http://something123.com",
    "label":"FOO123.jpg",
    "name":"FOO123",
    "srcName":"FOO123.jpg"
}]

script.rb:

dir = File.dirname(ARGV[0])
output = File.new(dir + "/output_" + Time.now.strftime("%H_%M_%S") + ".json", "w")
open(ARGV[0]).each do |x|
x = x.sub(ARGV[1]),'')
output.puts(x) if !x.nil?
end
output.close

这是非常基本的东西,但我不太清楚如何做到这一点。我试过了:

  • Regexp.escape使用此模式:[{"src":"
  • 逃避角色而不是逃避。
  • 在引号之间包裹模式而不包装。

3 个答案:

答案 0 :(得分:2)

默想:

我写了一个包含以下内容的小脚本:

puts ARGV[0].class 
puts ARGV[1].class

并将其保存到磁盘,然后使用以下命令运行:

ruby ~/Desktop/tests/test.rb foo /abc/

返回:

String
String

文档说:

  

该模式通常是Regexp;如果作为字符串给出,它包含的任何正则表达式元字符将按字面解释,例如, ' \ d'将匹配后跟'd'的反弹,而不是数字。

这意味着正则表达式,虽然它出现是一个正则表达式,但它不是一个字符串,因为ARGV只能返回字符串,因为命令行只能包含字符串。

当我们将字符串传递给sub时,Ruby认识到它不是正则表达式,因此它将其视为文字字符串。这是行动的不同之处:

'foo'.sub('/o/', '') # => "foo"
'foo'.sub(/o/, '') # => "fo"

第一个无法在"/o/"中找到"foo",因此没有任何变化。它可以找到/o/并在替换两个" o"后返回结果。

另一种看待它的方式是:

'foo'.match('/o/') # => nil
'foo'.match(/o/) # => #<MatchData "o">

match找不到该字符串的内容,但可以找到/o/的匹配。

所有这一切都会导致代码中发生的事情。由于sub正在传递一个字符串,它正在尝试为正则表达式进行字面匹配,并且无法找到它。您需要将代码更改为:

sub(Regexp.new(ARGV[1]), '')

但并非所有这一切都必须改变。 Regexp.new(...)会将传入的内容转换为正则表达式,但如果您传入'/o/',则生成的正则表达式将为:

Regexp.new('/o/') # => /\/o\//

这可能不是你想要的:

'foo'.match(/\/o\//) # => nil

相反,你想:

Regexp.new('o') # => /o/
'foo'.match(/o/) # => #<MatchData "o">

因此,除了更改代码之外,您还需要确保传入的内容是有效的表达式,减去任何前导和尾随/

答案 1 :(得分:0)

根据帖子this answer中的Convert a string to regular expression ruby,您应该使用

x = x.sub(/#{ARGV[1]}/,'')

答案 2 :(得分:0)

我用这个文件(test.rb)测试了它:

puts "You should not see any number [0123456789].".gsub(/#{ARGV[0]}/,'')

我这样称呼文件:

ruby test.rb "\d+"
# => You should not see any number [].