.vtt文件的PHP正则表达式

时间:2018-11-13 17:00:17

标签: php regex webvtt

我希望遍历现有的.vtt文件,并将提示数据读入数据库。

.vtt文件的格式为:

WEBVTT FILE

line1
00:00:00.000 --> 00:00:10.000
‘Stuff’

line2
00:00:10.000 --> 00:00:20.000
Other stuff
Example with 2 lines

line3
00:00:20.00 --> 00:00:30.000
Example with only 2 digits in milliseconds

line4
00:00:30.000 --> 00:00:40.000
Different stuff

00:00:40.000 --> 00:00:50.000
Example without a head line

最初,我试图使用^$来对/^(\w*)$^(\d{2}):(\d{2}):(\d{2})\.(\d{2,3}) --> (\d{2}):(\d{2}):(\d{2})\.(\d{2,3})$^(.+)$/ims的句法进行严格限制,但是我很难在正则表达式检查器中使它起作用,并且不得不采取措施使用\s处理行的开始/结束。

当前我正在使用以下正则表达式:/(.*)\s(\d{2}):(\d{2}):(\d{2})\.(\d{2,3}) --> (\d{2}):(\d{2}):(\d{2})\.(\d{2,3})\s(.+)/im

使用https://regex101.com/r/mmpObk/3这样的在线正则表达式检查器可以部分工作(此示例未选择多行字幕,但确实得到了第一行,这对我来说已经足够了,因为当前所有字幕都已1个衬板)。但是,如果我将其放入php(preg_match_all("/(.*)\s(\d{2}):(\d{2}):(\d{2})\.(\d{2,3}) --> (\d{2}):(\d{2}):(\d{2})\.(\d{2,3})\s(.+)/mi", $fileData, $matches))中并转储结果,则会得到一个空数组。

在线正则表达式和php有什么不同?

预先感谢您的任何建议。

编辑--- 以下是$ fileData和$ matches的转储:

string(341) "WEBVTT FILE

line1
00:00:00.000 --> 00:00:10.000
‘Stuff’

line2
00:00:10.000 --> 00:00:20.000
Other stuff
Example with 2 lines

line3
00:00:20.00 --> 00:00:30.000
Example with only 2 digits in milliseconds

line4
00:00:30.000 --> 00:00:40.000
Different stuff

00:00:40.000 --> 00:00:50.000
Example without a head line"

array(11) {
    [0]=>
        array(0) {}
    [1]=>
        array(0) {}
    [2]=>
        array(0) {}
    [3]=>
        array(0) {}
    [4]=>
        array(0) {}
    [5]=>
        array(0) {}
    [6]=>
        array(0) {}
    [7]=>
        array(0) {}
    [8]=>
        array(0) {}
    [9]=>
        array(0) {}
    [10]=>
        array(0) {}
}

1 个答案:

答案 0 :(得分:1)

正则表达式的问题是行尾处理不当。

您最后有这个:\s(.+)/mi
这只能匹配1个空格,但是换行符可以是1个或2个空格。

要解决此问题,可以使用\R(.+)/mi

它可以在网站上正常运行,因为它将您的换行符标准化为Linux风格的换行符。
也就是说,Windows风格的换行符为\r\n(2个字符),Linux风格的换行符为\n(1个字符)。


或者,您可以尝试以下正则表达式:

/(?:line(\d+)\R)?(\d{2}(?::\d{2}){2}\.\d{2,3})\s*-->\s*(\d{2}(?::\d{2}){2}\.\d{2,3})\R((?:[^\r\n]|\r?\n[^\r\n])*)(?:\r?\n\r?\n|$)/i

它看起来很恐怖,但是有效。
注意:我在\R\r\n之间交换,因为\RR中的文字[]匹配。

像这样捕获数据:

  1. 行号(如果有)
  2. 初始时间戳
  3. 最终时间戳
  4. 多行文字

您可以在https://regex101.com/r/Yk8iD1/1

上尝试

您可以使用方便的代码生成器工具生成以下PHP:

$re = '/(?:line(\d+)\R)?(\d{2}(?::\d{2}){2}\.\d{2,3})\s*-->\s*(\d{2}(?::\d{2}){2}\.\d{2,3})\R((?:[^\r\n]|\r?\n[^\r\n])*)(?:\r?\n\r?\n|$)/i';
$str = 'WEBVTT FILE

line1
00:00:00.000 --> 00:00:10.000
‘Stuff’

line2
00:00:10.000 --> 00:00:20.000
Other stuff
Example with 2 lines

line3
00:00:20.00 --> 00:00:30.000
Example with only 2 digits in milliseconds

line4
00:00:30.000 --> 00:00:40.000
Different stuff

00:00:40.000 --> 00:00:50.000
Example without a head line';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the entire match result
var_dump($matches);

您可以在http://sandbox.onlinephpfunctions.com/code/7f5362f56e912f3504ed075e7013071059cdee7b

上对其进行测试