2013-04-21 81 views
2

我想操縱SRT字幕文件。該文件的開始的示例串@dataRuby正則表達式忽略第一個有效的(?)匹配

1 
00:01:09,611 --> 00:01:12,404 
In co-production with 

2 
00:01:14,783 --> 00:01:17,034 
presents 

我用正則表達式的所有id的匹配:

@data.scan(/^\d+\w*$/) 

然而,這忽略了第一1,只有輸出2..900。我以爲我錯過了在正則表達式的一些字符,並分析@data

puts @data[0,10].inspect => "1\n00:01:09,611 --> " 

我不明白爲什麼這首1不匹配。與@data.match()一起運行它不會產生1,但會產生2

然後我在1之前加了一個\n,它就起作用了。但是,我不明白爲什麼^需要一個\n而不是真正的字符串開頭。

+0

似乎在字符串中的'1'之前有一些奇怪的字符。試試'p @data [0,10] .bytes'。第一個不是49. – Dogbert 2013-04-21 15:12:40

+1

明白了,字符串中的第一個字符似乎是UTF-8的Byte順序標記 - http://en.wikipedia.org/wiki/Byte_order_mark – Dogbert 2013-04-21 15:13:58

+0

'@ data.scan (/^\ d + \ w * $ /)在我的環境中給我'[「1」,「2」]'。 – sawa 2013-04-21 15:15:12

回答

2

正如@Dogbert在評論中指出的那樣,在字符串的開始處有一個Unicode BOM。我懷疑這是任何程序創作你正在閱讀的文件的人工製品。您可以解決這幾個方面 - 刪除字符:

@data = @data[1..-1] if @data[0] == "\ufeff" 
# or 
@data.sub!(/\A\ufeff/, '') 

或者讓你的正則表達式掃描對待BOM像線錨的開始以積極向後看:

@data.scan(/(?:^|(?<=\ufeff))\d+\w*$/) 

或者作爲鐵皮人所指出的,告訴Ruby來BOM感知讀取數據時:

@data = File.read('somedata', nil, 0, 'r:BOM|UTF-8') 
+0

我認爲的確如此。現在我認爲這是因爲我使用了一些簡單的OSX字幕編輯器,它抱怨編碼並將其保存爲utf。我想這是問題。我在開始的時候通過在linebreak中加入瞭解決方法,但如果有人需要定期處理這個問題,那麼您的答案中就會列出所有選項。公認。 – Peterdk 2013-04-21 22:19:19

3

如果問題是文檔中的BOM,Ruby支持讀取時使用多字節編碼沿檢查一個BOM文件。從IO.new的 「IO編碼」 文檔:

如果|「UTF16-BE BOM」時,紅寶石檢查一個Unicode BOM「BOM | | UTF-8」,「BOM UTF-16LE」或輸入文件以幫助確定編碼。對於UTF-16編碼,文件打開模式必須是二進制。如果存在,則剝離BOM並使用來自BOM的外部編碼。當BOM缺失時,給定的Unicode編碼被用作ext_enc。 (BOM-set編碼選項不區分大小寫,因此「bom | utf-8」也是有效的。)

+1

+1教導我們Ruby可以被告知做正確的事情與BOM – dbenhur 2013-04-21 15:52:32

+1

BOM一直是我身邊的刺多次。我遇到他們很少,我會忘記他​​們存在,直到我在我的輸入數據中得到垃圾。在我寫Perl時,我不得不處理它們,而且第一次遇到UTF-16編碼時感到震驚......「這些二進制零是什麼!!!」 :-)很高興看到Ruby有幫助。 – 2013-04-21 15:55:39