現在,當您已更新問題,我不得不刪除這麼好的答案的一大部分:-)
我想你的問題的要點是,你想用match[1]
而不是match
。 Regexp.match
方法(MatchData
)返回的對象可以像數組一樣對待,它將整個匹配的字符串保存爲第一個元素,並將每個子查詢保存在以下元素中。所以,在你的情況,可變match
(和match[0]
)是整個匹配的字符串(與「==頁.. ==」標誌一起),但你想要的只是它是隱藏在match[1]
第一個子表達式。
現在談談其他的小問題,我在你的代碼中感覺。如果你已經知道我在說什麼,請不要生氣,但也許其他人會從警告中獲益。
代碼(if File.exists? line
)的第一部分是檢查文件是否存在,但你的代碼只是打開該文件(不關閉它!),並仍試圖幾行後打開文件。
您可以使用此行:
next unless File.exists? line
的第二的是,該方案應準備處理時,該文件沒有頁面標記的情況,所以它不匹配的格局。 (可變match
隨後將被nil
)
的第三建議是有點複雜圖案可能被使用。當前的(/==Page 1==(.*)==Page 2==/m
)將返回帶有行尾標記的頁面內容作爲第一個字符。如果您使用此模式:
/==Page 1==\s*\n(.*)==Page 2==/m
那麼子表達式將不包含放置在同一行「== 1 =='文本的空格。如果你使用這個模式:
/==Page 1==\s*\n(.*\n)==Page 2==/m
,那麼你一定會認爲在「==第2個==」標誌,從該行的開頭開始。
而且第四問題是,很多時候程序員(有時也包括我,當然)傾向有關關閉文件他們打開後忘記。在你的情況下,你已經打開了'源'文件,但在代碼中循環後沒有source.close
語句。處理文件的最安全的方法是通過傳遞塊到File.open
方法,所以你可以使用你的程序的第一線以下形式:
File.open('list.txt') do |source|
source.readlines.each do |line|
...但在這種情況下,將清潔劑只寫:
File.readlines('list.txt').each do |line|
把它放在一起,代碼可能看起來像這樣(我改變了可變line
到fname
更好的代碼的可讀性):
#!/usr/bin/env ruby -wKU
require 'fileutils'
File.readlines('list.txt').each do |fname|
fname.strip!
next unless File.exists? fname
text = File.read(fname)
if match = text.match(/==Page 1==\s*\n(.*\n)==Page 2==/m)
# The whole 'page' (String):
puts match[1].inspect
# The 'page' without the first two lines:
# (in case you really wanted to delete lines):
puts match[1].split("\n")[2..-1].inspect
else
# What to do if the file does not match the pattern?
raise "The file #{fname} does NOT include the page separators."
end
end
你能表達一下你想要的代碼嗎?它看起來像這樣:我想刪除存儲在另一個文件中的列表中包含的每個文件的前兩行。那是對的嗎? – mliebelt
對不起 - 編輯。你是對的,想刪除我列表中每個文件的前兩行。 – chuckfinley
我已經更新了答案。我希望我已經找到你的問題:-) _(通過評論通知,因爲我不知道提問者是否收到有關答案更新的通知)_ – Arsen7