PHP Preg_匹配模式从字幕srt文件中删除时间

PHP Preg_匹配模式从字幕srt文件中删除时间,php,regex,preg-replace,preg-match,Php,Regex,Preg Replace,Preg Match,我需要一个preg_match表达式来删除.srt字幕文件(作为字符串导入)中的所有计时,但我始终无法完全理解正则表达式模式。例如,它会改变: 5 00:05:50,141 --> 00:05:54,771 This is what was said 到 因此,考虑到这是所说的以大写字母开头,可以是带有标点符号的文本,我建议如下: $re = '/.*([A-Z]{1}[A-Za-z0-9 _.,?!"\/\'$]*)/'; $str = '5 00:05:50,141 -->

我需要一个preg_match表达式来删除.srt字幕文件(作为字符串导入)中的所有计时,但我始终无法完全理解正则表达式模式。例如,它会改变:

5
00:05:50,141 --> 00:05:54,771
This is what was said


因此,考虑到
这是所说的
以大写字母开头,可以是带有标点符号的文本,我建议如下:

$re = '/.*([A-Z]{1}[A-Za-z0-9 _.,?!"\/\'$]*)/';

$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said.';

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

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

因此,考虑到
这是所说的
以大写字母开头,可以是带有标点符号的文本,我建议如下:

$re = '/.*([A-Z]{1}[A-Za-z0-9 _.,?!"\/\'$]*)/';

$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said.';

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

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

不确定您在哪里被卡住了,实际上只有\d+和冒号/逗号

$re = '/\d+.\d+:\d+:\d+,\d+\s-->\s\d+:\d+:\d+,\d+./s';
//$re = '\d+.[0-9:,]+\s-->\s[\d+:,]+./s'; //slightly compacter version of the regex
$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said';
$subst = '';

$result = preg_replace($re, $subst, $str);

echo $result;
工作演示。
使用“小压实器”图案,它看起来像:


只是为了好玩和挑战。这里有一个非正则表达式的答案

非正则表达式将首先在两行新行上拆分,这意味着每个新的字幕组都是数组中的一个新项。
然后在它们之间循环并在新行上再次爆发。
前两行不需要,数组将它们切掉。
如果字幕不止一行,我需要合并它们。在新的线路上使用内爆

然后,作为最后一步,在双新行上使用内爆再次重建字符串

正如Casimir在下面的评论中所写,我使用PHP_EOL作为新行,并且在示例中有效。
但在实际srt文件中使用时,新行可能会有所不同。
如果代码没有按预期工作,请尝试用其他新行替换PHP_EOL


不确定您在哪里被卡住了,实际上只有\d+和冒号/逗号

$re = '/\d+.\d+:\d+:\d+,\d+\s-->\s\d+:\d+:\d+,\d+./s';
//$re = '\d+.[0-9:,]+\s-->\s[\d+:,]+./s'; //slightly compacter version of the regex
$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said';
$subst = '';

$result = preg_replace($re, $subst, $str);

echo $result;
工作演示。
使用“小压实器”图案,它看起来像:


只是为了好玩和挑战。这里有一个非正则表达式的答案

非正则表达式将首先在两行新行上拆分,这意味着每个新的字幕组都是数组中的一个新项。
然后在它们之间循环并在新行上再次爆发。
前两行不需要,数组将它们切掉。
如果字幕不止一行,我需要合并它们。在新的线路上使用内爆

然后,作为最后一步,在双新行上使用内爆再次重建字符串

正如Casimir在下面的评论中所写,我使用PHP_EOL作为新行,并且在示例中有效。
但在实际srt文件中使用时,新行可能会有所不同。
如果代码没有按预期工作,请尝试用其他新行替换PHP_EOL

PHP代码:

$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said';
$reg = '/(.{0,}[0,1]{0,}\s{0,}[0-9]{0,}.{0,}[0-9]+[0-9]+:[0-9]{0,}.{0,})/';
echo(trim(preg_replace($reg, '', $str)));
PHP代码:

$str = '5
00:05:50,141 --> 00:05:54,771
This is what was said';
$reg = '/(.{0,}[0,1]{0,}\s{0,}[0-9]{0,}.{0,}[0-9]+[0-9]+:[0-9]{0,}.{0,})/';
echo(trim(preg_replace($reg, '', $str)));

由于srt文件的格式始终相同,因此可以跳过每个行块的前两行,并在到达空行后返回结果。为此,为了避免将整个文件加载到内存中,您可以逐行读取文件并使用生成器:

function getSubtitleLine($handle) {
    $flag = 0;
    $subtitle = '';
    while ( false !== $line = stream_get_line($handle, 1024, "\n") ) {
        $line = rtrim($line);
        if ( empty($line) ) {
            yield $subtitle;
            $subtitle = '';
            $flag = 0;
        } elseif ( $flag == 2 ) {
            $subtitle .= empty($subtitle) ? $line : "\n$line";
        } else {
           $flag++;
        }
    }

    if ( !empty($subtitle) )
        yield $subtitle;
}

if ( false !== $handle = fopen('./test.srt', 'r') ) {
    foreach (getSubtitleLine($handle) as $line) {
        echo $line, PHP_EOL;
    }
}

由于srt文件的格式始终相同,因此可以跳过每个行块的前两行,并在到达空行后返回结果。为此,为了避免将整个文件加载到内存中,您可以逐行读取文件并使用生成器:

function getSubtitleLine($handle) {
    $flag = 0;
    $subtitle = '';
    while ( false !== $line = stream_get_line($handle, 1024, "\n") ) {
        $line = rtrim($line);
        if ( empty($line) ) {
            yield $subtitle;
            $subtitle = '';
            $flag = 0;
        } elseif ( $flag == 2 ) {
            $subtitle .= empty($subtitle) ? $line : "\n$line";
        } else {
           $flag++;
        }
    }

    if ( !empty($subtitle) )
        yield $subtitle;
}

if ( false !== $handle = fopen('./test.srt', 'r') ) {
    foreach (getSubtitleLine($handle) as $line) {
        echo $line, PHP_EOL;
    }
}


你有没有更多的例子,让我们看看它们是如何变化的@道格,他们真的没有。第一个数字是副标题、新行的计数,然后是开始时间和结束时间。然后是新行和文本。你有没有更多的例子,让我们看看它们是如何变化的。像这样@道格,他们真的没有。第一个数字是副标题、新行的计数,然后是开始时间和结束时间。然后是新行和文本。谢谢阿拉文德。忘记链接了。有谁能对否决票发表评论吗?我做错了什么?不是我投了反对票。我会试试的。效果绝对完美!了不起的工作。是的,当我试图使用正则表达式时,我从一开始就被卡住了,我现在不知道如何使用它。@Hasen谢谢。我刚刚注意到我在紧凑正则表达式中犯了一个错误。A+不见了,谢谢阿拉文德。忘记链接了。有谁能对否决票发表评论吗?我做错了什么?不是我投了反对票。我会试试的。效果绝对完美!了不起的工作。是的,当我试图使用正则表达式时,我从一开始就被卡住了,我现在不知道如何使用它。@Hasen谢谢。我刚刚注意到我在紧凑正则表达式中犯了一个错误。A+丢失。请记住它是字幕文件。就像你在电影和电视节目中看到的字幕一样。因此,我认为需要的不仅仅是A-z,它可能会起作用。但是如果您想在srt文件上使用Preg_match。我的最佳猜测是使用文件类型的规范对您有利。我的意思是,文件类型必须在副标题的计数和上一个副标题文本之间有一个空的行。因此,在上面的例子中,“5”有一条空行,在空白行上方有“字幕计数4的文本”。所以任何时间和空白线(懒惰)都会是文本。(至少应该是)下面是如何使用preg_match_all构建srt文件。因为文件中可能有多个字幕行。请记住它是字幕文件。就像你在电影和电视节目中看到的字幕一样。因此,我认为需要的不仅仅是A-z,它可能会起作用。但是如果您想在srt文件上使用Preg_match。我的最佳猜测是使用文件类型的规范对您有利。我的意思是,文件类型必须在副标题的计数和上一个副标题文本之间有一个空的行。因此,在上面的例子中,“5”有一条空行,在空白行上方有“字幕计数4的文本”。所以任何时间和空白线(懒惰)都会是文本。(至少应该是)下面是如何使用preg_match_all构建srt文件。因为文件中可能有多行字幕。