开发者

How to modify specific lines in text file using C#?

开发者 https://www.devze.com 2023-03-29 08:56 出处:网络
I have srt file with movie subtitles like this: 1 00:00:00,082 --> 00:00:04,352 bbb bbb bb bbb bb 2 00:00:08,486 --> 00:开发者_运维技巧00:12,662

I have srt file with movie subtitles like this:

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 bbb

3

00:00:12,824 --> 00:00:14,963

bbb

bbbb bb

I want to add constant value to minutes (so subtitles will be displayed later). How can i do this?

I already have this code:

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());
                }
            }
        }
    }
}


This is a complete program to do it. Just change the timespan to be how much you want to add

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);
        }


I would use a regular expression matching the lines

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

and then use Regex.Replace with a custom MatchEvaluator, which parses the time code, adds the time difference and returns the new time code as string.

A simple Regex for the time code would be

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

For the evaluator, you could construct two TimeSpan values from the respective fields of the match, add the time difference and construct the result string using String.Format.

This way, you can load the entire text file into a string using File.ReadAllText, process it and write it back using File.WriteAllText, which makes the core routine a three-liner :)

PS: Don't forget to use the RegexOptions.Multiline option in order to get "^" and "$" to work correctly.


    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"); 
    }

Replace sb.AppendLine(sr.ReadLine()); with sb.AppendLine(ProcessLine(sr.ReadLine(), 60)); in your original code.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号