-3

私は NSString 操作にまったく慣れておらず、実際にどの言語でも文字列を操作した経験があまりありません。

私の問題は、大量のデータを含む文字列があることです。このデータ内には、新しい NSString に抽出する必要がある名前があります。例えば:

NSString* dataString =@"randomdata12359123888585/name_john_randomdatawadapoawdk"

「/name_」は常に必要なデータの前にあり、「_」は常にその後に続きます。

NSScanner などを調べましたが、正しいアプローチが何であるか、または NSScanner を実装する方法がよくわかりません。

4

3 に答える 3

3

あなたの文字列形式は非常に明確に定義されています(あなたが言うように、あなたの名前の前には常に「/ name_」が続き、常に「_」が続きます)。したがって、名前(「john」)には下線。

したがって、この種の問題に完全に適した単純な正規表現を検討します。

NSString *regexPattern = @"^.*/name_(.*?)_.*$";

NSString *name = [dataString stringByReplacingOccurrencesOfString: regexPattern 
                                                       withString: @"$1"
                                                          options: NSRegularExpressionSearch
                                                            range: NSMakeRange(0, dataString.length)];

正規表現に慣れていない方のために説明すると、次のようになります。

  1. 文字列の先頭 (「^」) から開始します。
  2. "/name_" が後に続くすべて (".*") を許可する
  3. 次のものをキャプチャします(括弧は「これをキャプチャする」を意味します)
  4. 括弧内は何でも構いませんが (".*")、できるだけ短くしてください ("*" の後の "?")。
  5. アンダースコアが続き、文字列の最後 (「$」) までそこにあるものをすべて許可する必要があります。

これは文字列全体に一致し、一致 (つまり、文字列全体) を "$1" で置き換える場合、最初の (そして唯一の) 括弧に含まれる部分文字列で一致を置き換えます。

結果: 名前のみを含む文字列が生成されます。文字列の形式が正しくない場合 (つまり、2 つのアンダースコアの間に名前がない場合)、何も変更されず、完全な元の文字列が返されます。

いずれかのアプローチを好むかどうかはコーディング スタイルの問題ですが、正規表現が好きな場合、このアプローチはクリーンで理解しやすく、保守も簡単です。

私が見ているように、これの脆弱性はデータ形式が原因であり、他の「ランダムな」データに依存するもののように疑わしく見えるため、その文字列を解析するために選択した方法に関係なく、防御テストを追加するようにしてくださいデータ形式を確認し、予期しない文字列がデータに入力され始めた場合に警告します。アンダースコア、正規表現、NSScanner.

于 2013-06-16T14:56:23.977 に答える
1

NSScanner でこれを行うことができましたが、配列の回答も機能するため、賛成しました。

同様の問題に直面している他の人に使用した NSScanner コードは次のとおりです。

-(void)formatName{
NSString *stringToSearch = _URLString; //url string is the long string we wish to search.

NSScanner *scanner = [NSScanner scannerWithString:stringToSearch];
[scanner scanUpToString:@"name_" intoString:nil]; // Scan all characters before name_
while(![scanner isAtEnd]) {
    NSString *substring = nil;
    [scanner scanString:@"name_" intoString:nil]; // Scan the # character
    if([scanner scanUpToString:@"_" intoString:&substring]) {
        // If the space immediately followed the _, this will be skipped

        _nameIwant = substring; //nameIwant is a property to store the name I scanned for
        return;
    }

}

}

于 2013-06-16T14:38:00.027 に答える
1
-(void)separateString{
NSString* dataString =@"randomdata12359123888585/name_john_randomdatawadapoawdk";
NSArray *arr1 = [dataString componentsSeparatedByString:@"/"];
NSArray *arr2 = [[arr1 objectAtIndex:1] componentsSeparatedByString:@"_"];
NSLog(@"%@ %@",arr1,arr2);
}

得られる出力は

arr1=  (
randomdata12359123888585,
"name_john_randomdatawadapoawdk"
) 
arr2 = (
name,
john,
randomdatawadapoawdk
)

これで、配列インデックスから名前などにアクセスできるようになりました。

于 2013-06-16T13:29:20.800 に答える