2011-11-10 78 views
4

我的腳本讀入大型文本文件,並用正則表達式抓取第一頁。我需要刪除每個第一頁的前兩行或更改正則表達式匹配== 1字符串後的1行。我在這裏包括了整個劇本,因爲我一直在問到過去的問題,因爲我是新來的Ruby和總是不知道怎麼片段作爲整合的答案:用ruby刪除前兩行文件

#!/usr/bin/env ruby -wKU 
require 'fileutils' 

source = File.open('list.txt') 
source.readlines.each do |line| 
    line.strip! 
    if File.exists? line 
    file = File.open(line) 
    end 

    text = (File.read(line)) 
    match = text.match(/==Page 1(.*)==Page 2==/m) 
    puts match 
end 
+0

你能表達一下你想要的代碼嗎?它看起來像這樣:我想刪除存儲在另一個文件中的列表中包含的每個文件的前兩行。那是對的嗎? – mliebelt

+0

對不起 - 編輯。你是對的,想刪除我列表中每個文件的前兩行。 – chuckfinley

+0

我已經更新了答案。我希望我已經找到你的問題:-) _(通過評論通知,因爲我不知道提問者是否收到有關答案更新的通知)_ – Arsen7

回答

3

現在,當您已更新問題,我不得不刪除這麼好的答案的一大部分:-)

我想你的問題的要點是,你想用match[1]而不是matchRegexp.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| 

把它放在一起,代碼可能看起來像這樣(我改變了可變linefname更好的代碼的可讀性)

#!/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