0

次のコードでは、正規表現を使用して、テキスト ファイルのさらに下の部分を抽出しようとしています。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
    NSString *string = [[NSString alloc] initWithData:receivedData encoding:NSISOLatin1StringEncoding];
    NSLog(@"string length: %d", [string length]);
    NSError *error = nil;
    NSString *toMatch = @"\[Board\\t\"([0-9]?)\"]*\[Dealer\\t\"([NEWS])\"]*";
    NSRegularExpression *regex = [NSRegularExpression  regularExpressionWithPattern:toMatch
        options:0 error:&error];
    NSLog(@"length: %d", [toMatch length]);
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
    NSLog(@" %ud", numberOfMatches);
    for (NSTextCheckingResult* match in [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])]){
        // cannot make this work: NSRange trange =[match range];
        // cannot make this work: NSLog(@"range %i,%i", trange );
        NSString* tstring=[string substringWithRange:trange];
        NSLog(@" %@", tstring );}
}

NSRegularExpression抜粋した次のテキストから情報を抽出するために使用しています。特に、各ボードのBoard番号とDealer値が必要です (約 40 のボードがあり、リストから無関係な行をいくつか削除しました)。

[Board "1"]
[Dealer "N"]
[Vulnerable "None"]
[Deal "N:Q952.652.KJT4.95 T.KQT84.A865.J73 K8763.A7.Q.KQT84 AJ4.J93.9732.A62"]
[Scoring ""]
[Declarer ""]
[Contract ""]
[Board "2"]
[Dealer "E"]
[Vulnerable "NS"]
[Deal "E:K8542.3.4.AT7532 J76.K7.AT85.KQJ8 QT3.AJ84.KJ963.4 A9.QT9652.Q72.96"]
[Scoring ""]
[Declarer ""]
[Contract ""]

forループのプリントアウトに gobbledygook を取得しています。gobbledygook には少なくとも 2 つの理由があります。正規表現が間違っているか、forループが間違っています。

コンソール出力とgobbledygook以下。

2013-02-03 11:00:14.161 BridgeDuplicate[51867:11303] the window: <UIWindow: 0x956eac0; frame = (0 0; 768 1024); hidden = YES; layer = <UIWindowLayer: 0x956ebc0>>
2013-02-03 11:00:14.163 BridgeDuplicate[51867:11303] the rootViewController: <BSViewController: 0x7188220>
2013-02-03 11:00:14.166 BridgeDuplicate[51867:11303] viewDidLoad
2013-02-03 11:00:27.156 BridgeDuplicate[51867:11303] Succeeded! Received 303896 bytes of data
2013-02-03 11:00:27.158 BridgeDuplicate[51867:11303] string length: 303896
2013-02-03 11:00:27.164 BridgeDuplicate[51867:11303] length: 41
2013-02-03 11:00:27.205 BridgeDuplicate[51867:11303]  264765d
2013-02-03 11:00:27.205 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  l
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.206 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  ea
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  d
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.207 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  e
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  a
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.208 BridgeDuplicate[51867:11303]  e
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.209 BridgeDuplicate[51867:11303]  "
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  o
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  e
2013-02-03 11:00:27.228 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.229 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.229 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.229 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.229 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.229 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.230 BridgeDuplicate[51867:11303]  e"
2013-02-03 11:00:27.230 BridgeDuplicate[51867:11303]  
2013-02-03 11:00:27.230 BridgeDuplicate[51867:11303]  
4

1 に答える 1

1

の仕組みを誤解していると思われますがNSTextCheckingResult、おそらくもっと重要なのは、パターンにいくつかの問題があることです。次のコードは実例です。

NSString *string = @"[Board\t\"1\"]\n[Dealer\t\"N\"]\n";
NSLog(@"string length: %lu", (unsigned long)[string length]);
NSError *error = nil;
NSString *toMatch = @"\\[Board\\t\"([0-9]?)\"\\].*\\n\\[Dealer\\t\"([NEWS])\"\\].*";
NSRegularExpression *regex = [NSRegularExpression  regularExpressionWithPattern:toMatch options:0 error:&error];
NSLog(@"length: %lu", (unsigned long)[toMatch length]);
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
NSLog(@"number of matches: %lu", (unsigned long)numberOfMatches);
for (NSTextCheckingResult* match in [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])])
{
    NSLog(@"Number of ranges in match: %lu", match.numberOfRanges);
    for (NSUInteger i = 0; i < match.numberOfRanges; ++i)
    {
        NSRange matchedRange = [match rangeAtIndex: i];
        NSString* tstring = [string substringWithRange: matchedRange];
        NSLog(@"range %lu string: %@", (unsigned long)i, tstring);
    }
}

これから得られることは次のとおりです。

2013-02-03 12:16:41.112 RegExTest[72290:303] string length: 25
2013-02-03 12:16:43.889 RegExTest[72290:303] length: 49
2013-02-03 12:16:43.889 RegExTest[72290:303] number of matches: 1
2013-02-03 12:16:43.890 RegExTest[72290:303] Number of ranges in match: 3
2013-02-03 12:16:43.890 RegExTest[72290:303] range 0 string: [Board "1"]
[Dealer "N"]
2013-02-03 12:16:43.890 RegExTest[72290:303] range 1 string: 1
2013-02-03 12:16:43.890 RegExTest[72290:303] range 2 string: N

ここで知っておくべきことは、1 つのマッチを狙っており、そのマッチには複数の射程があるということです。成功したすべての一致には、少なくとも 1 つの範囲があります。つまり、パターン全体と一致した文字列全体の範囲 (これはここで関心のあることではありません)。括弧ベースのキャプチャ グループは、示されているように、0 を超えるインデックスに表示されます。このコードによって。

エスケープ ルールはちょっと厄介です。NSString でエスケープするためのルールと、正規表現をエスケープするためのルールがあります。それらがどのように相互作用するかは明らかではありませんが、ここで思いついたパターンは、あなたが求めていることを行うようです.

編集:

URL から直接取得し、正常に一致する別のバージョンを次に示します。

NSError* error = nil;
NSString* string = [NSString stringWithContentsOfURL: [NSURL URLWithString: @"http://www.atlantaduplicatebridgeclub.com/scorepost/2013/01/20130126ana.pbn"]
                                            encoding: NSUTF8StringEncoding error: &error];
NSLog(@"string length: %lu", (unsigned long)[string length]);
NSString *toMatch = @"\\[Board\\s*\"([0-9]?)\"\\].*\\[Dealer\\s*\"([NEWS])\"\\]";
NSRegularExpression *regex = [NSRegularExpression  regularExpressionWithPattern:toMatch options:NSRegularExpressionDotMatchesLineSeparators error:&error];
NSLog(@"pattern length: %lu", (unsigned long)[toMatch length]);
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
NSLog(@"number of matches: %lu", (unsigned long)numberOfMatches);
for (NSTextCheckingResult* match in [regex matchesInString:string options:NSRegularExpressionDotMatchesLineSeparators range:NSMakeRange(0, [string length])])
{
    NSLog(@"Number of ranges in match: %lu", match.numberOfRanges);
    for (NSUInteger i = 0; i < match.numberOfRanges; ++i)
    {
        NSRange matchedRange = [match rangeAtIndex: i];
        NSString* tstring = [string substringWithRange: matchedRange];
        NSLog(@"range %lu string: %@", (unsigned long)i, tstring);
    }
}
于 2013-02-03T17:24:18.083 に答える