44

このコードがキャプチャグループではなく正規表現の一致全体を吐き出すだけなのはなぜですか?

入力

@"A long string containing Name:</td><td>A name here</td> amongst other things"

期待される出力

A name here

実際の出力

Name:</td><td>A name here</td>

コード

NSString *htmlString = @"A long string containing Name:</td><td>A name here</td> amongst other things";
NSRegularExpression *nameExpression = [NSRegularExpression regularExpressionWithPattern:@"Name:</td>.*\">(.*)</td>" options:NSRegularExpressionSearch error:nil];

NSArray *matches = [nameExpression matchesInString:htmlString
                                  options:0
                                    range:NSMakeRange(0, [htmlString length])];
for (NSTextCheckingResult *match in matches) {
    NSRange matchRange = [match range];
    NSString *matchString = [htmlString substringWithRange:matchRange];
    NSLog(@"%@", matchString);
}

Appleドキュメントから取得したコード。これを行うための他のライブラリがあることは知っていますが、このタスクに組み込まれているものを使い続けたいと思います。

4

4 に答える 4

74

次を使用して最初のグループ範囲にアクセスします。

for (NSTextCheckingResult *match in matches) {
    //NSRange matchRange = [match range];
    NSRange matchRange = [match rangeAtIndex:1];
    NSString *matchString = [htmlString substringWithRange:matchRange];
    NSLog(@"%@", matchString);
}
于 2011-07-25T22:04:17.557 に答える
11

HTML を正規表現または NSScanner で解析しないでください。その道の下には狂気が横たわっています。

これはSOで何度も尋ねられました。

iPhone での HTML の解析

私が選んでいるデータは単純<td>Name: A name</td>で、プロジェクトに本格的な HTML パーサーを含める代わりに、正規表現を使用するだけで十分単純だと思います。

あなた次第で、私は「最初に市場に出ることには大きな利点がある」ことを強く支持します。

違いは、適切な HTML パーサーを使用すると、ドキュメントの構造を考慮していることです。正規表現を使用すると、ドキュメントが構文的に完全に有効な方法でフォーマットを変更しないことに依存しています。

つまり、入力が<td class="name">Name: A name</td>? 正規表現パーサーは、有効な HTML であり、タグの内容の観点からすると、元の入力と同一の入力で壊れました。

于 2011-07-25T22:03:27.947 に答える
4

Swift3で

//: Playground - noun: a place where people can play

import UIKit

/// Two groups. 1: [A-Z]+, 2: [0-9]+
var pattern = "([A-Z]+)([0-9]+)"

let regex = try NSRegularExpression(pattern: pattern, options:[.caseInsensitive])

let str = "AA01B2C3DD4"
let strLen = str.characters.count
let results = regex.matches(in: str, options: [], range: NSMakeRange(0, strLen))

let nsStr = str as NSString

for a in results {

    let c = a.numberOfRanges 
    print(c)

    let m0 = a.rangeAt(0)  //< Ex: 'AA01'
    let m1 = a.rangeAt(1)  //< Group 1: Alpha chars, ex: 'AA'
    let m2 = a.rangeAt(2)  //< Group 2: Digital numbers, ex: '01'
    // let m3 = a.rangeAt(3) //< Runtime exceptions

    let s = nsStr.substring(with: m2)
    print(s)
}
于 2017-02-07T07:12:51.293 に答える