3 votes

Correspondance RegEx pour la syntaxe SRT et VTT des sous-titres

J'ai des sous-titres en format srt et vtt pour lesquels je dois faire correspondre et supprimer la syntaxe spécifique au format et obtenir des lignes propres avec le texte.

J'ai trouvé cette regex : /\n?\d*?\n?^.* --> [012345]{2}:.*$/m

Contenu de l'échantillon (mélange de srt et de vtt) :

1
00:00:04,019 --> 00:00:07,299
line1
line2

2
00:00:07,414 --> 00:00:09,155
line1

00:00:09,276 --> 00:00:11,429
line1

00:00:11,549 --> 00:00:14,874
line1
line2

Cela correspond au numéro de sous-titre et à l'heure comme prévu, simulé en https://regex101.com/r/zRsRMR/2/

Mais lorsqu'il est utilisé dans le code lui-même (même en utilisant directement l'extrait de code généré à partir de https://regex101.com ), qui ne correspondra qu'au minutage, et non au numéro de sous-titre.

Voir la sortie :

array (5)
0 => array (1)
0 => "00:00:04,019 --> 00:00:07,299
" (30)
1 => array (1)
0 => "
00:00:07,414 --> 00:00:09,155
" (31)
2 => array (1)
0 => "
00:00:09,276 --> 00:00:11,429
" (31)
3 => array (1)
0 => "
00:00:11,549 --> 00:00:14,874
" (31)
4 => array (1)
0 => "
00:00:11,549 --> 00:00:14,874
" (31)

Peut être testé sur : http://sandbox.onlinephpfunctions.com/code/dec294251b879144f40a6d1bdd516d2050321242

L'objectif est de faire correspondre même le numéro du sous-titre, par exemple la première correspondance attendue devrait être :

1
00:00:04,019 --> 00:00:07,299

4voto

Emma Points 1

Je ne sais pas si c'est ce que vous souhaitez obtenir. Cependant, la raison en est que vous pouvez vouloir envelopper votre chaîne avec des groupes de capture pour qu'elle soit simple à obtenir. Par exemple, cette expression exemples de la façon dont les groupes de capture fonctionnent autour des caractères souhaités :

^([0-9]+\n|)([0-9:,->\s]+)

enter image description here

Ce n'est peut-être pas la meilleure façon de le faire, ni la meilleure expression. Cependant, cela peut vous donner une idée pour aborder le problème différemment.

Je suppose que vous souhaitez capturer la ligne de la date et les lignes qui la précèdent, qui peuvent ou non contenir un nombre.

Graphique

Ce graphique montre comment l'expression fonctionnerait et vous pouvez visualiser d'autres expressions de cette manière. enlace :

enter image description here

Vous pourriez vouloir écrire un script pour nettoyer vos données, avant de les envoyer au moteur RegEx, afin d'obtenir une expression simple.

Exemple de test avec JavaScript

const regex = /^([0-9]+\n|)([0-9:,->\s]+)/mg;
const str = `1
00:00:04,019 --> 00:00:07,299
line1
line2

2
00:00:07,414 --> 00:00:09,155
line1

00:00:09,276 --> 00:00:11,429
line1

00:00:11,549 --> 00:00:14,874
line1
line2
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Test PHP

Il se peut que vous n'obteniez pas le résultat souhaité, il s'agit simplement d'un exemple :

$re = '/^([0-9]+\n|)([0-9:,->\s]+)/m';
$str = '1
00:00:04,019 --> 00:00:07,299
line1
line2

2
00:00:07,414 --> 00:00:09,155
line1

00:00:09,276 --> 00:00:11,429
line1

00:00:11,549 --> 00:00:14,874
line1
line2
';

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

foreach ($matches[0] as $key => $value) {
    if ($value == "") {
        unset($matches[0][$key]);
    } else {
        $matches[0][$key] = trim($value);
    }

}

var_dump($matches[0]);

Test de performance

Cet extrait de JavaScript montre les performances de cette expression en utilisant un simple 1 million de fois. for boucle.

repeat = 1000000;
start = Date.now();

for (var i = repeat; i >= 0; i--) {
    var string = '2  \n00:00:07,414 --> 00:00:09,155';
    var regex = /(.*)([0-9:,->\s]+)/gm;
    var match = string.replace(regex, "$2");
}

end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");

Si vous souhaitez capturer tous les résultats souhaités dans une seule variable, vous pouvez simplement ajouter un groupe de capture autour de l'expression entière et l'appeler en utilisant $1 .

Vous pouvez également ajouter ou réduire des limites, si vous le souhaitez, telles que éste .

^(?:[0-9]+\n|\n)(([0-9:,]+)([\s->]+)([0-9:,]+))$

enter image description here

enter image description here

Exemple Test avec JavaScript pour la deuxième expression

const regex = /^(?:[0-9]+\n|\n)(([0-9:,]+)([\s->]+)([0-9:,]+))$/gm;
const str = `1
00:00:04,019 --> 00:00:07,299
- cdcdc
- cddcd

2
00:00:07,414 --> 00:00:09,155
54564

00:00:09,276 --> 00:00:11,429
- 445454 - ccd
- cdscdcdcd

00:00:11,549 --> 00:00:14,874
line1
line2
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

3voto

The fourth bird Points 40138

Vous pouvez inclure ce point dans votre expression \n?\d*?\n? un groupe facultatif correspondant à plus d'un chiffre, suivi d'un saut de ligne. La classe de caractères [012345] peut également s'écrire [0-5]

Vous pourriez mettre à jour votre expression en :

^(?:\d+\n)?.*\h+-->\h+[0-5]{2}:.*$
  • ^ Début de la chaîne
  • (?:\d+\n)? Facultatif : 1+ chiffres et nouvelle ligne
  • .*\h+-->\h+ Match 0+ times any char except newline, 1+ horizontal whitespace chars, -->` et plus de 1 caractère d'espacement horizontal
  • [0-5]{2}: Match 2 fois 0-5
  • .* Correspondance 0+ fois avec n'importe quel caractère à l'exception de la nouvelle ligne
  • $ Fin de la chaîne

Démonstration des expressions rationnelles Démonstration Php

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X