使用 ARGV[] 参数向量在 Ruby 中传递正则表达式
Use ARGV[] argument vector to pass a regular expression in Ruby
我正在尝试在通过终端传递给 ARGV[]
的正则表达式上使用 gsub
或 sub
。
终端查询:$ruby script.rb input.json "\[\{\"src\"\:\"
输入文件前两行:
[{
"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":"
.
- 转义字符不转义
- 在引号之间换行和不换行。
基于this answer in the thread Convert a string to regular expression ruby,你应该使用
x = x.sub(/#{ARGV[1]}/,'')
我用这个文件测试过它 (test.rb):
puts "You should not see any number [0123456789].".gsub(/#{ARGV[0]}/,'')
我这样调用文件:
ruby test.rb "\d+"
# => You should not see any number [].
对此进行冥想:
我写了一个小脚本包含:
puts ARGV[0].class
puts ARGV[1].class
并将其保存到磁盘,然后 运行 使用:
ruby ~/Desktop/tests/test.rb foo /abc/
return编辑:
String
String
文档说:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\d' will match a backlash followed by ‘d’, instead of a digit.
这意味着正则表达式,虽然看起来是一个正则表达式,但它不是,它是一个字符串,因为ARGV
只能return 字符串,因为命令行只能包含字符串。
当我们将字符串传递给 sub
时,Ruby 识别出它不是正则表达式,因此将其视为文字字符串。这是操作上的差异:
'foo'.sub('/o/', '') # => "foo"
'foo'.sub(/o/, '') # => "fo"
第一个在 "foo"
中找不到 "/o/"
,所以没有任何变化。它可以找到 /o/
和 returns 替换两个 "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">
因此,除了更改代码外,您还需要确保传入的内容是有效的表达式,减去 任何前导和尾随 /
。
我正在尝试在通过终端传递给 ARGV[]
的正则表达式上使用 gsub
或 sub
。
终端查询:$ruby script.rb input.json "\[\{\"src\"\:\"
输入文件前两行:
[{
"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":"
.- 转义字符不转义
- 在引号之间换行和不换行。
基于this answer in the thread Convert a string to regular expression ruby,你应该使用
x = x.sub(/#{ARGV[1]}/,'')
我用这个文件测试过它 (test.rb):
puts "You should not see any number [0123456789].".gsub(/#{ARGV[0]}/,'')
我这样调用文件:
ruby test.rb "\d+"
# => You should not see any number [].
对此进行冥想:
我写了一个小脚本包含:
puts ARGV[0].class
puts ARGV[1].class
并将其保存到磁盘,然后 运行 使用:
ruby ~/Desktop/tests/test.rb foo /abc/
return编辑:
String
String
文档说:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\d' will match a backlash followed by ‘d’, instead of a digit.
这意味着正则表达式,虽然看起来是一个正则表达式,但它不是,它是一个字符串,因为ARGV
只能return 字符串,因为命令行只能包含字符串。
当我们将字符串传递给 sub
时,Ruby 识别出它不是正则表达式,因此将其视为文字字符串。这是操作上的差异:
'foo'.sub('/o/', '') # => "foo"
'foo'.sub(/o/, '') # => "fo"
第一个在 "foo"
中找不到 "/o/"
,所以没有任何变化。它可以找到 /o/
和 returns 替换两个 "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">
因此,除了更改代码外,您还需要确保传入的内容是有效的表达式,减去 任何前导和尾随 /
。