2

我正在尝试操作 SRT 字幕文件。文件开头的示例字符串@data

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

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

id我将所有的's 与正则表达式匹配:

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

但是,这忽略了第一个1,也是唯一的 output 2..900。我以为我错过了正则表达式中的一些字符,并分析了@data

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

我不明白为什么这首先1不匹配。也运行它@data.match()不会产生12.

\n然后我在 之前添加了一个1,它起作用了。但是,我不明白为什么^需要 a\n而不是字符串的真正开头。

4

2 回答 2

3

如果问题是文档中的 BOM,Ruby 支持在读取文件时检查 BOM 以及使用多字节编码。来自IO.new的“IO 编码”文档:

如果使用“BOM|UTF-8”、“BOM|UTF-16LE”或“BOM|UTF16-BE”,ruby 会检查输入文档中的 Unicode BOM 以帮助确定编码。对于 UTF-16 编码,文件打开模式必须是二进制的。当存在时,将剥离 BOM 并使用 BOM 中的外部编码。当 BOM 缺失时,给定的 Unicode 编码用作 ext_enc。(BOM 集编码选项不区分大小写,因此“bom|utf-8”也是有效的。)

于 2013-04-21T15:49:47.830 回答
2

正如@Dogbert 在评论中指出的那样,您的字符串开头有一个Unicode BOM 。我怀疑这是编写您正在阅读的文件的任何程序的工件。您可以通过几种方式解决此问题 - 删除字符:

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

或者让您的扫描正则表达式将 BOM 视为行锚的开头,并具有积极的后视:

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

或者,正如 Tin Man 指出的那样,让 ruby​​ 在读取数据时了解 BOM:

@data = File.read('somedata', nil, 0, 'r:BOM|UTF-8')
于 2013-04-21T15:30:47.630 回答