【问题标题】:Tokenizing and parsing a text file (edit decision list ASCII text file) Objective C标记和解析文本文件(编辑决策列表 ASCII 文本文件)目标 C
【发布时间】:2012-03-20 17:03:42
【问题描述】:

我是编程和 stackoverflow 的新手,我决定从学习目标 c 开始。

在最深处,我知道。

我一直在努力寻找解析 edl 文件的最佳方法。 它基本上是一个不超过 100KB 的 ASCII 文本文件。 下面是一个典型的cmx3600 edl的结构:

TITLE:   EP1 FINAL.EDL SECTION2
FCM: NON-DROP FRAME
001  A199_C00 V     C        20:38:24:15 20:38:26:04 10:30:00:02 10:30:01:16
* SOURCE FILE: A199_C008_0915AH_001
002  A199_C00 V     C        20:34:48:17 20:34:51:23 10:30:01:16 10:30:04:22
* SOURCE FILE: A199_C007_0915VE_001

我正在尝试找出将每个元素解析或扫描到字段/数组中的最佳方法,即,

editNum = 001
tapeName = A199_C00
channel = V
Operation = C
sourceIn = 20:38:24:15
sourceOut = 20:38:26:04
recIn = 10:30:00:02
recOut = 10:30:01:16
sourceFile = A199_C008_0915AH_001

这是我目前的代码:

-(IBAction)importEdl:(id)sender {    

    //defines an Array of allowed file types with file extension ".EDL and .edl"

    NSOpenPanel *myPanel = [NSOpenPanel openPanel];
    NSArray *fileTypes = [NSArray arrayWithObjects:@"EDL", @"edl", nil];
    myPanel.allowedFileTypes = fileTypes;
    myPanel.allowsMultipleSelection = NO;

    if ([myPanel runModal] == NSOKButton)
    {            

    NSString *theFilePath = [myPanel filename];
    NSString *psEdlFile = [NSString stringWithContentsOfFile:theFilePath encoding:NSASCIIStringEncoding error:NULL];
        // Reads the file as one string. EDL's are simple ASCII text files of roughly 50KB.

    NSArray *psEdlLines = [psEdlFile componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];   
        // Separates the data into lines.

    if([psEdlLines count] == 0)
    {
        NSLog(@"Error!");                                  
    } //prints error if EDL file has no events.


    NSUInteger count;
    int i;
    for (i = 0, count = [psEdlLines count]; i < count; i = i + 1)
    {
        NSString *lineStrings = [psEdlLines objectAtIndex:i];
        NSLog(@"Line %d is %@",i+1,lineStrings);

    //NSArray *linesEnum = [psEdlLines objectAtIndex:i];
        //this creates an array of lines

    //NSLog(@"index is: %d %@",i, linesEnum);
    }

    }                

}

@end

输出是:

2012-03-20 15:22:08.956 TestProgram[412:903] Line 1 is TITLE:   EP1 FINAL.EDL SECTION2
2012-03-20 15:22:08.957 TestProgram[412:903] Line 2 is FCM: NON-DROP FRAME
2012-03-20 15:22:08.957 TestProgram[412:903] Line 3 is 001  A199_C00 V     C        20:38:24:15 20:38:26:04 10:30:00:02 10:30:01:16
2012-03-20 15:22:08.957 TestProgram[412:903] Line 4 is * SOURCE FILE: A199_C008_0915AH_001
2012-03-20 15:22:08.957 TestProgram[412:903] Line 5 is 002  A199_C00 V     C        20:34:48:17 20:34:51:23 10:30:01:16 10:30:04:22
2012-03-20 15:22:08.957 TestProgram[412:903] Line 6 is * SOURCE FILE: A199_C007_0915VE_001
2012-03-20 15:22:08.957 TestProgram[412:903] Line 7 is 003  A199_C00 V     C        20:42:32:01 20:42:35:19 10:30:04:22 10:30:08:15
2012-03-20 15:22:08.957 TestProgram[412:903] Line 8 is * SOURCE FILE: A199_C009_0915RX_001
2012-03-20 15:22:08.957 TestProgram[412:903] Line 9 is 
2012-03-20 15:22:08.958 TestProgram[412:903] Line 10 is 

如你所见,我还没有走多远。 任何想法将不胜感激。 提前致谢, 皮特。

【问题讨论】:

  • 如果你在做解析,那么要走的路是BNF语法。构建并使用它将是一个很好的学习练习。
  • ParseKit
  • 或者,NSScanner,如果您是 Cocoa 的新手,并且想接触原生框架。
  • 感谢您的及时回复。看来我还有点阅读工作要做。

标签: objective-c arrays parsing ascii tokenize


【解决方案1】:

好的,

我一直试图通过使用 NSScanner 和行前缀来解决这个问题。 我可以扫描以数字开头的行(事件),并隔离与每个相应事件相关的注释和效果。

代码如下:

for (NSString *line in psEdlLines)// just an NSLog test before scanning process 
    {
        NSLog(@"Before scanner: %@",line);//All lines.
    }

for (NSString *line in psEdlLines)// Scanner process.
        {

        int eventNum;
        NSString *comment;
        NSString *effect;
        NSScanner *lineScanner = [NSScanner scannerWithString:line];

while ([lineScanner scanInt:&eventNum]) 
        {
            NSLog(@"Scanner: Event only: %@:", line);
        }

    if ([line hasPrefix:@"*"]) 
        {
                comment = [line substringFromIndex:0];
            NSLog(@"Comment for event    %03i: %@",eventNum, comment);
        }

    if ([line hasPrefix:@"M2"]) 
            {
                effect = [line substringFromIndex:0];
            NSLog(@"Effect for event     %03i:    %@",eventNum, effect);
            }
}
@end

这是 3 事件 edl 文件的输出:

2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: TITLE:   EP1 FINAL.EDL SECTION2
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: FCM: NON-DROP FRAME
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 001  A180_C00 V     C        20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: * SOURCE FILE: A180_C001_09138L_001
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 002  A181_C01 V     C        22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: * SOURCE FILE: A181_C010_0913EA_001
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: 003  A181_C01 V     C        22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09
2012-03-23 14:23:48.040 TestProgram[1621:903] Before scanner: M2   A181_C01       000.0                22:10:05:09
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: * * FREEZE FRAME
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: * SOURCE FILE: A181_C010_0913EA_001
2012-03-23 14:23:48.041 TestProgram[1621:903] Before scanner: 
2012-03-23 14:23:48.041 TestProgram[1621:903] Scanner: Event only: 001  A180_C00 V     C        20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23:
2012-03-23 14:23:48.041 TestProgram[1621:903] Comment for event    001 * SOURCE FILE: A180_C001_09138L_001
2012-03-23 14:23:48.041 TestProgram[1621:903] Scanner: Event only: 002  A181_C01 V     C        22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04:
2012-03-23 14:23:48.041 TestProgram[1621:903] Comment for event    002 * SOURCE FILE: A181_C010_0913EA_001
2012-03-23 14:23:48.042 TestProgram[1621:903] Scanner: Event only: 003  A181_C01 V     C        22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09:
2012-03-23 14:23:48.042 TestProgram[1621:903] Effect for event     003    M2   A181_C01       000.0                22:10:05:09
2012-03-23 14:23:48.042 TestProgram[1621:903] Comment for event    003 * * FREEZE FRAME
2012-03-23 14:23:48.042 TestProgram[1621:903] Comment for event    003 * SOURCE FILE: A181_C010_0913EA_001

我可以为 edl 文件的注释行中可能出现的所有可能性添加 if 语句。 这应该允许我在循环中根据需要处理每个行元素。

这看起来好吗?

谢谢, 皮特。

【讨论】:

    【解决方案2】:

    更多进展。

    if ([lineScanner scanInt:&eventNum])
        {
            // parse the event into fields
    
            // does not work if edl contains dissolve or wipe
            // need to automatically convert dissolves into cuts
    
             NSString *editNum;
             NSString *reelName;
             NSString *channels;
             NSString *operation;
             //NSString *opDuration;
             NSString *sourceInTime;
             NSString *sourceOutTime;
             NSString *destInTime;
             NSString *destOutTime;
    
            NSScanner *elementScanner = [NSScanner scannerWithString:line];
    
            //NSString *token = [NSString string];
            NSCharacterSet *divider = [NSCharacterSet whitespaceCharacterSet];
    
            [elementScanner scanUpToCharactersFromSet:divider intoString:&editNum];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&reelName];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&channels];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&operation];
            //[elementScanner scanUpToCharactersFromSet:divider intoString:&opDuration];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&sourceInTime];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&sourceOutTime];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&destInTime];
            [elementScanner scanUpToCharactersFromSet:divider intoString:&destOutTime];
    
    
            NSLog(@"Event\tReelName\tChannels\tOperation\tSource In\tSource Out\tDest In\t\tDest Out");
            NSLog(@"%@\t%@\t%@\t\t\t%@\t\t\t%@\t%@\t%@\t%@", 
                  editNum, reelName, channels, operation, /*opDuration,*/ sourceInTime, sourceOutTime, destInTime,destOutTime);
    
        }
    

    输出以下内容。

    2012-03-29 15:54:15.489 TestProgram[2414:903] Scanner:Title = EP1 FINAL.EDL SECTION2
    2012-03-29 15:54:15.489 TestProgram[2414:903] Event ReelName    Channels    Operation   Source In   Source Out  Dest In     Dest Out
    2012-03-29 15:54:15.489 TestProgram[2414:903] 001   A180_C00    V           C           20:29:12:18 20:29:13:21 10:46:39:20 10:46:40:23
    2012-03-29 15:54:15.489 TestProgram[2414:903] Comment for event    001 * SOURCE FILE: A180_C001_09138L_001
    2012-03-29 15:54:15.489 TestProgram[2414:903] Event ReelName    Channels    Operation   Source In   Source Out  Dest In     Dest Out
    2012-03-29 15:54:15.490 TestProgram[2414:903] 002   A181_C01    V           C           22:10:03:03 22:10:05:09 10:46:40:23 10:46:43:04
    2012-03-29 15:54:15.490 TestProgram[2414:903] Comment for event    002 * SOURCE FILE: A181_C010_0913EA_001
    2012-03-29 15:54:15.490 TestProgram[2414:903] Event ReelName    Channels    Operation   Source In   Source Out  Dest In     Dest Out
    2012-03-29 15:54:15.490 TestProgram[2414:903] 003   A181_C01    V           C           22:10:05:09 22:10:05:10 10:46:43:04 10:46:43:09
    2012-03-29 15:54:15.490 TestProgram[2414:903] Effect for event     003    M2   A181_C01       000.0                22:10:05:09
    2012-03-29 15:54:15.491 TestProgram[2414:903] Comment for event    003 * * FREEZE FRAME
    2012-03-29 15:54:15.491 TestProgram[2414:903] Comment for event    003 * SOURCE FILE: A181_C010_0913EA_001
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-12
      • 2018-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-07
      • 2016-01-09
      • 2011-06-29
      相关资源
      最近更新 更多