考虑代码:
output = `cat test.txt`
puts output # /^\\([0-3][0-9]\\/[0-1][0-9]\\/[2-9][0-9]{3}\\)$/
str = 'test ' + output
puts str # test /^\\([0-3][0-9]\\/[0-1][0-9]\\/[2-9][0-9]{3}\\)$/
new_str = 'new test ' + output
puts new_str # new test /^\\([0-3][0-9]\\/[0-1][0-9]\\/[2-9][0-9]{3}\\)$/
res = str.sub('test', 'new test')
puts res # new test /^\\([0-3][0-9]\\/[0-1][0-9]\\/[2-9][0-9]{3}\\)$/ <-- all fine
res = str.sub(str, new_str)
puts res # new test /^\([0-3][0-9]\/[0-1][0-9]\/[2-9][0-9]{3}\)$/ <-- !!! problem
代码仅用于说明我所遇到的问题;)
问题:我有带双反斜杠的替换文本,需要将“原样”写到另一个文件中
问题是:是否有任何不解释反斜杠的简单替换方法(也许是二进制模式)?
因为这样做很奇怪:res = str.sub(str, new_str.gsub('\\', '\\\\\\\\'))
,尽管这样做可行...
实际工作代码:
file = 'some/random/file.php'
contents = new_contents = ''
File.open(file, 'rb') do |f|
contents = new_contents = f.read
end
contents.scan(/('([A-Z]+)' \=\> \<\<\<'JSON'(.*?)JSON)/m) do |match|
Dir.glob("*#{match[1]}.json") do |filename|
compressed = `../compress.py #{filename}`.gsub('\\', '\\\\\\\\')
replacement = match[0].sub(match[2], "\n" + compressed).force_encoding('ASCII-8BIT')
new_contents = new_contents.sub(match[0], replacement.gsub('\\', '\\\\\\\\'))
end
end
File.open(file, 'wb') do |f|
f.write(new_contents)
end
答案 0 :(得分:2)
最终我找到了一个非常简单的解决方案:
input = '{"regex": "/^\\\\([0-3][0-9]\\\\)$/"}'
puts input # gives => {"regex": "/^\\([0-3][0-9]\\)$/"}
search = '/^\\\\([0-3][0-9]\\\\)$/'
replace = '/^\\\\([0-9]\\\\)$/'
puts input.sub(search, replace) # gives => {"regex": "/^\([0-9]\)$/"}, which is wrong result
input[search] = replace # <-- here is the trick, but makes changes in place
puts input # gives => {"regex": "/^\\([0-9]\\)$/"} => success!
但是!如果您的字符串不包含任何search
子字符串,您将得到一个string not matched (IndexError)
。
因此,您可能需要这样对代码进行防弹:
input[search] = replace if input.include? search
此外,如果您希望保持input
不变,则可以将其.dup
更改为另一个变量:
new_input = input.dup
new_input[search] = replace if new_input.include? search
答案 1 :(得分:1)
您可以使用范围替换字符串的一部分。所以你只需要找到那个范围
if index = string.index(str_to_replace)
string[index...(index + str_to_replace.length)] = replacement
end
此示例已就位,因此如有必要,请对它进行复制。
答案 2 :(得分:0)
否,每个Ruby String文字都必须转义反斜杠。 Ruby允许这样的任意String 分隔符:
%q{A string}
%Q<A string>
%.A string.
请参见ruby-doc.org和wikibooks.org。但是,所有这些都将反斜杠视为特殊字符,并要求将其转义。
一种选择是将替换项放入数据文件(例如CSV)中,并按如下方式读取替换项:
while line = data_file.gets
pattern, replacement = *line.split(separator)
str.gsub!(Regexp.compile(pattern), replacement)
end
数据文件不需要需要转义替换中的任何字符。