Как изменить конкретные строки в текстовом файле с помощью C #? - PullRequest
3 голосов
/ 21 августа 2011

У меня есть файл srt с такими субтитрами к фильму:

1
00: 00: 00,082 -> 00: 00: 04,352
BBB BBB BB
BBB BB

2
00: 00: 08,486 -> 00: 00: 12,662
BBB BBB

3
00: 00: 12,824 -> 00: 00: 14,963
БББ
bbbb bb

Я хочу добавить постоянное значение в минуты (чтобы субтитры отображались позже). Как я могу это сделать?

У меня уже есть этот код:

class MainClass
{

    public static void Main (string[] args)
    {
        StringBuilder sb = new StringBuilder();

        using(FileStream fs = new FileStream(@"sb.srt",FileMode.Open,FileAccess.ReadWrite))
        {
            using(StreamReader sr = new StreamReader(fs))
            {
                while( sr.Read()!=-1 )
                {
                    sb.AppendLine(sr.ReadLine());
                }
            }
        }
    }
}

Ответы [ 3 ]

4 голосов
/ 21 августа 2011

Это полная программа для этого. Просто измените временной интервал на то, сколько вы хотите добавить

const string format = @"hh\:mm\:ss\,fff";
        static void Main(string[] args)
        {
            string input = File.ReadAllText("sb.srt");
            Regex r = new Regex(@"(\d\d):(\d\d):(\d\d),(\d\d\d)");
            input = r.Replace(input, m=> AddTime(m));
            File.WriteAllText("sb.srt", input);
        }

        private static string AddTime(Match m)
        {
            TimeSpan t = TimeSpan.ParseExact(m.Value, format, CultureInfo.InvariantCulture);
            t += new TimeSpan(0, 1, 0);
            return t.ToString(format);
        }
2 голосов
/ 21 августа 2011

Я бы использовал регулярное выражение, соответствующее строкам

00:00:08,486 --> 00:00:12,662

, а затем использовал бы Regex.Replace с пользовательским MatchEvaluator, который анализирует временной код, добавляет разницу во времени и возвращает новый временной кодв виде строки.

Простое регулярное выражение для временного кода будет

"^\s*(\d\d):(\d\d):(\d\d),(\d\d\d)\s*-->\s*(\d\d):(\d\d):(\d\d),(\d\d\d)\s*$"

Для оценщика вы можете построить два TimeSpan значения из соответствующих полей совпадения, добавить времяРазница и построить результирующую строку, используя String.Format.

Таким образом, вы можете загрузить весь текстовый файл в строку, используя File.ReadAllText, обработать его и записать обратно, используя File.WriteAllText, что делает ядроподпрограмма с тремя строками:)

PS: не забудьте использовать опцию RegexOptions.Multiline, чтобы "^" и "$" работали правильно.

1 голос
/ 21 августа 2011
    private static string ProcessLine(string line, int seconds)
    {
        var regex = new Regex(@"^(\d\d:\d\d:\d\d,\d\d\d) --> (\d\d:\d\d:\d\d,\d\d\d)");

        var match = regex.Match(line);

        if (match.Success)
        {
            var from = AddSeconds(match.Groups[1].ToString(), seconds);
            var to = AddSeconds(match.Groups[2].ToString(), seconds);
            return string.Format("{0} --> {1}", from, to);
        }
        else
        {
            return line;
        }
    }

    private static string AddSeconds(string timestamp, int seconds)
    {
        var datetime = DateTime.ParseExact(timestamp, "HH:mm:ss,fff", CultureInfo.InvariantCulture);
        return datetime.AddSeconds(seconds).ToString("HH:mm:ss,fff"); 
    }

Замените sb.AppendLine(sr.ReadLine()); на sb.AppendLine(ProcessLine(sr.ReadLine(), 60)); в исходном коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...