2015-08-19 1 views
2

J'ai un fichier « srt » (comme format standard sous-titre de film) comme indiqué en lien ci-dessous:
http://pastebin.com/3k8a53SCCan ajouter un nombre particulier à un groupe de « temps » des chaînes, être fait dans Regex

Extrait:

1 
00:00:53,000 --> 00:00:57,000 
<any text that may span multiple lines> 

2 
00:01:28,000 --> 00:01:35,000 
<any text that may span multiple lines> 

Mais maintenant le timing des sous-titres est tout faux, car il est en retard de 9 secondes.

Est-il possible d'ajouter 9 secondes (+9) à chaque entrée de temps avec regex? Même si millisecondes est défini sur 000 alors c'est bien, mais l'ajout de 9 secondes doit respecter les règles "60 secondes = 1 minute & 60 minutes = 1 heure". De même, le texte de sous-titre après l'entrée de temporisation ne doit pas être modifié par regex. Par ailleurs, le format d'heure pour chaque chaîne de temps est "Heures: Minutes: Seconds.Millisecondes".

+0

Quelle langue ou quel outil utilisez-vous? –

Répondre

0

Les expressions régulières correspondent strictement et ne peuvent pas ajouter/soustraire. Vous pouvez faire correspondre chaque chaîne datetime en utilisant python, par exemple, ajouter 9 secondes à cela, puis réécrire la chaîne à l'endroit approprié. L'expression régulière, j'utiliser pour le match serait la suivante:

(?<hour>\d+):(?<minute>\d+):(?<second>\d+),(?<msecond>\d+) 

Il a marqué des groupes de capture il est vraiment facile d'obtenir chaque section (vous aurez pas besoin msecond mais il est là pour la visualisation, je suppose)

Regex101

0

non, désolé, vous ne pouvez pas. Regex est un langage sans contexte (voir Chomsky, par exemple https://en.wikipedia.org/wiki/Chomsky_hierarchy) et vous ne pouvez pas calculer. Mais avec un langage contextuel tel que perl, cela fonctionnera. Il pourrait être une doublure comme ça ;-)))

perl -n -e 'if(/^(\d\d:\d\d:\d\d)([-,\d\s\>]*)(\d\d:\d\d:\d\d)(.*)/) {print plus9($1).$2.plus9($3).$4."\n";}else{print $_} sub plus9{ ($h,$m,$s)=split(/:/,shift); $t=(($h*60+$m)*60+$s+9); $h=int($t/3600);$r=$t-($h*3600);$m=int($r/60);$s=$r-($m*60);return sprintf "%02d:%02d:%02d", $h, $m, $s;}‘ movie.srt 

avec move.srt comme

1 
00:00:53,000 --> 00:00:57,000 
hello 

2 
00:01:28,000 --> 00:01:35,000 
I like perl 

3 
00:02:09,000 --> 00:02:14,000 
and regex 

vous obtiendrez

1 
00:01:02,000 --> 00:01:06,000 
hello 

2 
00:01:37,000 --> 00:01:44,000 
I like perl 

3 
00:02:18,000 --> 00:02:23,000 
and regex 

Vous pouvez changer la +9 en le "sub plus9 {...}", si vous voulez un autre delta.

Comment ça marche? Nous recherchons des lignes qui correspondent dd:dd:dd something dd:dd:dd something puis nous appelons un sous-marin, qui ajoute 9 secondes au groupe un (1 $) et au groupe trois (3 $). Toutes les autres lignes sont imprimées inchangées.

ajouté Si vous voulez mettre le oneliner perl dans un fichier, par exemple plus9.pl, vous pouvez ajouter des sauts de ligne ;-)

if(/^(\d\d:\d\d:\d\d)([-,\d\s\>]*)(\d\d:\d\d:\d\d)(.*)/) { 
    print plus9($1).$2.plus9($3).$4."\n"; 
} else { 
    print $_ 
} 

sub plus9{ 
    ($h,$m,$s)=split(/:/,shift); 
    $t=(($h*60+$m)*60+$s+9); 
    $h=int($t/3600); 
    $r=$t-($h*3600); 
    $m=int($r/60); 
    $s=$r-($m*60); 
    return sprintf "%02d:%02d:%02d", $h, $m, $s; 
} 
+0

Merci pour la réponse, j'ai windows 7 pc, et dans cmd quand je lance votre commande ci-dessus, il donne le message "Le nom du fichier, nom du répertoire ou la syntaxe de l'étiquette de volume est incorrecte" (perl est déjà installé). Alors pouvez-vous mettre à jour cette commande pour Windows 7? –

+0

Mmmh, qu'avez-vous eu avec la commande perl -V? Est-ce que ça marche? Vous devriez obtenir une information de version de perl. –

+0

Oui, comme je vous l'ai dit, perl est installé et fonctionne avec ENV PATH set, quand je lance "perl -v" je reçois le numéro de version qui est 5.20.quelque chose dans mon cas. –

0

réponse rapide est « non », ce n'est pas une application pour regex. Une expression régulière vous permet de CORRESPONDRE au texte, mais de ne pas le modifier. Changer des choses est en dehors de la portée de la regex elle-même, et tombe dans la langue que vous utilisez - perl, awk, bash, etc.

Pour la tâche d'ajuster l'heure dans un fichier SRT, vous pouvez le faire assez facilement dans bash, en utilisant la commande date pour ajuster les temps.

#!/usr/bin/env bash 

offset="${1:-0}" 

datematch="^(([0-9]{2}:){2}[0-9]{2}),[0-9]{3} --> (([0-9]{2}:){2}[0-9]{2}),[0-9]{3}" 

os=$(uname -s) 

while read line; do 
    if [[ "$line" =~ $datematch ]]; then 

    # Gather the start and end times from the regex 
    start=${BASH_REMATCH[1]} 
    end=${BASH_REMATCH[3]} 

    # Replace the time in this line with a printf pattern 
    linefmt="${line//[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/%s}\n" 

    # Calculate new times 
    case "$os" in 
     Darwin|*BSD) 
     newstart=$(date -v${offset}S -j -f "%H:%M:%S" "$start" '+%H:%M:%S') 
     newend=$(date -v${offset}S -j -f "%H:%M:%S" "$end" '+%H:%M:%S') 
     ;; 
     Linux) 
     newstart=$(date -d "$start today ${offset} seconds" '+%H:%M:%S') 
     newend=$(date -d "$end today ${offset} seconds" '+%H:%M:%S') 
     ;; 
    esac 

    # And print the result 
    printf "$linefmt" "$newstart" "$newend" 

    else 
    # No adjustments required, print the line verbatim. 
    echo "$line" 
    fi 
done 

Notez l'instruction case. Ce script doit ajuster automatiquement pour Linux, Mac OS X, FreeBSD, etc.

Vous souhaitez utiliser ce script comme ceci:

$ ./srtadj -9 <input.srt> output.srt 

En supposant que vous l'avez nommé, bien sûr. Ou plus probablement, vous adapteriez sa logique pour l'utiliser dans votre propre script.