5

テキストの例:

1
00:00:00,000 --> 00:00:01,000
This is the first line

2
00:00:01,000 --> 00:00:02,000
This is the second line

3
00:00:02,000 --> 00:00:03,000
This is the last line

JavaScriptでは、これを正規表現で確実に解析します。私はただ疑問に思っています、それはObj Cでこれを行うための最良の方法ですか?私はこれを行う方法を見つけることができると確信していますが、私はそれを適切な方法で行いたいと思っています。

どこから始めればよいかを知る必要があるだけで、残りの作業は喜んで行いますが、理解のために、次のようなものになります(擬似コード)。

NSDictionary
index -> [0-9]+
start -> hh:mm:ss,mmm
end -> hh:mm:ss,mmm
text -> one of the lines of text

この場合、辞書に3つのエントリを解析します。

4

3 に答える 3

12

背景:小さなアプリを作成し、バンドルに含まれるサンプルを含むstuff.srtというファイルを作成しました。したがって、それにアクセスするための私の手段。

これは、迅速で汚いことであり、概念実証です。結果をチェックしないことに注意してください。実際のアプリケーションは常に結果をチェックします。ご覧のとおり、作業は-applicationDidFinishLaunching:メソッドで行われます(私はiOSではなくMac OS Xで作業しています)。

編集:

最初に投稿されたコードが複数のテキスト行を正しく処理していなかったことが指摘されています。これに対処するために、SRTファイルが改行としてCRLFを使用するという事実を利用して、このシーケンスの2つのオカレンスを検索します。次に、ここで観察した内容に基づいて、テキスト文字列内のCRLFのすべての出現箇所をスペースに変更します。これは、テキストの各行の先頭または末尾のスペースを考慮していません。

stuff.srtファイルの内容を次のように変更しました。

1
00:00:00,000 --> 00:00:01,000
This is the first line
and it has a secondary line

2
00:00:01,000 --> 00:00:02,000
This is the second line

3
00:00:02,000 --> 00:00:03,000
This is the last line
and it has a secondary line too

また、コードは次のように改訂されています(@autoreleasepoolディレクティブにもすべてを入れています。ファイルの解析中に、自動解放されたオブジェクトが多数生成される可能性があります!):

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stuff" ofType:@"srt"];

    NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];

    NSScanner *scanner = [NSScanner scannerWithString:string];

    while (![scanner isAtEnd])
    {
        @autoreleasepool
        {
            NSString *indexString;
            (void) [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&indexString];

            NSString *startString;
            (void) [scanner scanUpToString:@" --> " intoString:&startString];

            // My string constant doesn't begin with spaces because scanners
            // skip spaces and newlines by default.
            (void) [scanner scanString:@"-->" intoString:NULL];

            NSString *endString;
            (void) [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&endString];

            NSString *textString;
            // (void) [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&textString];
            // BEGIN EDIT
            (void) [scanner scanUpToString:@"\r\n\r\n" intoString:&textString];
            textString = [textString stringByReplacingOccurrencesOfString:@"\r\n" withString:@" "];
            // Addresses trailing space added if CRLF is on a line by itself at the end of the SRT file
            textString = [textString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
            // END EDIT

            NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                        indexString, @"index",
                                        startString, @"start",
                                        endString , @"end",
                                        textString , @"text",
                                        nil];

            NSLog(@"%@", dictionary);
        }
    }
}

改訂された出力は次のようになります。

2013-02-09 16:10:17.727 SRTFileScan[4846:303] {
    end = "00:00:01,000";
    index = 1;
    start = "00:00:00,000";
    text = "This is the first line and it has a secondary line";
}
2013-02-09 16:10:17.729 SRTFileScan[4846:303] {
    end = "00:00:02,000";
    index = 2;
    start = "00:00:01,000";
    text = "This is the second line";
}
2013-02-09 16:10:17.730 SRTFileScan[4846:303] {
    end = "00:00:03,000";
    index = 3;
    start = "00:00:02,000";
    text = "This is the last line and it has a secondary line too";
}

今日読んだことから学んだもう1つのことは、SRTファイル形式はフランスで生まれたものであり、入力に表示されるコンマはそこで使用される小数点記号です。

于 2013-01-11T23:38:35.903 に答える
1

Appleには、字幕ファイルを解析するためのサンプルコードがあります。ここで関連する部分を確認してください:

https://developer.apple.com/library/mac/samplecode/avsubtitleswriterOSX/Listings/avsubtitleswriter_SubtitlesTextReader_m.html#//apple_ref/doc/uid/DTS40013409-avsubtitleswriter_SubtitlesTextReader_m-DontLinkElementID_5

于 2015-05-13T12:48:16.203 に答える
0

私の提案は、NSDateFormatterを使用して2行目を解析することです。その文字列を2つの文字列に分割します(NSStringクラスリファレンスのcomponentsSeparatedByString:を参照)。これは、1行ごとにファイル行を読み取ります。

したがって、ループは次のようになります。

  • ファイルに再びデータが含まれている場合は、次の行を読んでください。
  • 次の行が4の倍数である場合は、新しいオブジェクトを割り当てます。このオブジェクトには、1つの整数と1つの文字列の2つの日付を含めることができる必要があります。
  • 次の行が4の倍数でない場合は、その行を読み取り、その値を対応するフィールドに割り当てます。
于 2013-01-14T17:00:35.397 に答える