php regex чтение определенных строк

#php #regex #match

#php #регулярное выражение #совпадение

Вопрос:

У меня проблема. Я пытаюсь подсчитать количество строк субтитров с помощью php. Как вы, возможно, знаете, подзаголовок выглядит следующим образом:

 1
00:00:00,984 --> 00:00:03,503
All right, guys, let's get to it.

2
00:00:03,587 --> 00:00:04,821
What's that button?

3
00:00:04,872 --> 00:00:07,590
It's something designed
to help you get healthy.

4
00:00:07,658 --> 00:00:09,676
Just ignore it.

5
00:00:09,760 --> 00:00:12,962
So, Patrick, did you take the high road
  

Теперь я попытался поместить содержимое файла субтитров в массив, вот так:

 $f = fopen($file, 'rb');
$read = fread($f, filesize($file));
fclose($f);
$array = explode("n",$read);
  

С помощью этого кода:

 $array = array_filter($array,'trim');
foreach($array as $key => $value) {
    if(preg_match('/d /',$value)) {
        unset($array[$key]);
    }
}
$array = array_values($array);
echo '<pre>';
print_r($array);
echo '</pre>';
  

я получаю:

   Array
(
[0] => All right, guys, let's get to it.
[1] => What's that button?
[2] => It's something designed
[3] => to help you get healthy.
[4] => Just ignore it.
[5] => So, Patrick, did you take the high road
[6] => and congratulate Wendy on that promotion
[7] => that you were supposed to get?
[8] => Yes, I did. I even bought her flowers.
[9] => Liar!
 )
  

что не нормально, потому что

  It's something designed
 to help you get healthy.
  

должно быть a в одном элементе массива.

Я также попытался сопоставить все между (пример) :

 1
00:00:00,984 --> 00:00:03,503
  

и

 2
00:00:03,587 --> 00:00:04,821
  

с:

 (d n)([0-9][0-9]:[0-9][0-9]:[0-9][0-9],d  --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9],d n).*n
  

но это не работает, и у меня закончились идеи.

Что я пытаюсь вывести:

 Array
(
[0] => All right, guys, let's get to it.
[1] => What's that button?
[2] => It's something designed to help you get healthy.
[3] => Just ignore it.
[4] => So, Patrick, did you take the high road
[5] => and congratulate Wendy on that promotion that you were supposed to get?
[6] => Yes, I did. I even bought her flowers.
[7] => Liar!
 )
 echo count($array); //for the previous array , should echo 8
  

Любая помощь будет оценена.

Ответ №1:

Вы можете использовать многострочный модификатор в PCRE для обработки встроенных новых строк после чтения в файле; а затем сопоставлять строки, не начинающиеся с числа, чтобы получить то, что вы хотите:

 $file = "./subtitles.txt";
$content = file_get_contents($file);

$blocks = preg_split('/^s*$/m', $content);
// var_export($blocks);

$subtitles = array();
for ($i=0; $i < count($blocks); $i  ) {
    $lines = explode("n", $blocks[$i]);
    $matches = preg_grep("/^[^d]/", $lines);
    array_push($subtitles, implode(' ', $matches));
}

print_r($subtitles);
  

Что дает вам следующий результат:

 Array
(
    [0] => All right, guys, let's get to it.
    [1] => What's that button?
    [2] => It's something designed to help you get healthy.
    [3] => Just ignore it.
    [4] => So, Patrick, did you take the high road
)
  

Комментарии:

1. Это простой способ сделать это.

Ответ №2:

Вот макет:

 $array = array(1, '00', 'one', 2, '00', 'two', 'abc', 3, '00', 'three', 4, '00', 'four', 'five', 5, '00', 'six', 6, '00', 'seven');

$string_last = 0; // keep track when last element was string
$string_array = array(); // new array to add elements I want to keep
$ii = 0;
foreach($array as $key => $value) {
    if(preg_match('/^d /',$value)) { // check if first character in line is a digit
        $string_last = 0; // if so, then last element is not string, go to next line
    }

    // we have string line
    else {
      if ( !$string_last ) { $ii  ; } // if last element was not a string, increment index
      else { $string_array[$ii] .= ' '; } // ...otherwise add a space
      $string_array[$ii] .= $value;
      $string_last = 1;
    }
}
echo '<pre>';
print_r($string_array);
echo '</pre>';
  

Вместо того, чтобы отключать ненужные элементы, я добавляю нужные элементы в новый массив. Таким образом, я могу объединить последовательные строковые элементы в один элемент в моем новом массиве.

Ответ №3:

Вы можете сделать это следующим образом, используя библиотеку https://github.com/mantas-done/subtitles

 $subtitles = Subtitles::load('subtitles.srt');
$blocks = $subtitles->getInternalFormat();
$array = [];
foreach ($blocks as $block) {
    $array[] = implode(' ', $block['lines']);
}

print_r($array);