文字列検索の方法5選!Objective-Cでマスターする

Objective-Cのコード例を表す画面、rangeOfStringメソッドを使った文字列検索のイラストObjctive-C
この記事は約23分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングにおける文字列検索は、情報処理の基本であり、多くのアプリケーションで必須の機能です。

Objective-Cを用いた開発においても、文字列検索は日常茶飯事となる作業で、その中心にあるのがrangeOfStringメソッドです。

この記事では、Objective-CのrangeOfStringメソッドを用いた文字列検索技術について、基礎から応用まで分かりやすく解説していきます。

Objective-Cでの文字列検索は、その豊富なライブラリとフレームワークによって簡単に実装できますが、それらの正しい使い方を理解することが重要です。

ここでは、初心者でも理解しやすいようにrangeOfStringメソッドの基本的な使い方から始め、段階的に複雑な使用例に進んでいきます。

●Objective-CのrangeOfStringとは

Objective-CにおいてNSStringクラスは、文字列操作の中心的な役割を担います。

rangeOfStringメソッドは、このNSStringクラスに属し、指定された部分文字列の範囲を検索するために使用されます。

このメソッドは、検索したい部分文字列とオプションを引数として受け取り、見つかった部分文字列の位置と長さをNSRange構造体で返します。

このメソッドの返り値は、部分文字列が見つかった場合にその範囲を表し、見つからなかった場合にはNSNotFoundという特別な値が設定されたNSRangeを返します。

これにより、開発者は文字列内での特定のテキストの存在有無や位置を簡単に把握することができます。

○rangeOfStringの基本的な理解

rangeOfStringメソッドの基本的な理解を深めるために、簡単な概念から始めましょう。

このメソッドは、主に2つのパラメータを取ります。

1つ目は検索する対象の文字列であり、2つ目は検索オプションです。検索オプションを使うことで、大文字と小文字を区別するかどうか、ロケールを考慮するかなど、検索方法を細かく設定することができます。

たとえば、ある文字列が別の文字列内に存在するかどうかを単純に判断したい場合、rangeOfStringメソッドを使用して、該当する部分文字列のNSRangeを取得します。

返されたNSRangelocationNSNotFoundでない場合、その文字列は存在するということになります。

●rangeOfStringの使い方

Objective-Cでの文字列操作は基本的なプログラミングスキルの一つであり、その中でもrangeOfStringメソッドは特に有用です。

このメソッドは、ある文字列(the “target” string)内で別の文字列(the “search” string)を検索し、その位置を特定するために使われます。

結果はNSRange構造体で返され、見つかった場合はその範囲を、見つからない場合は{NSNotFound, 0}を返します。

ここで言う範囲とは、検索文字列が開始するインデックスと検索文字列の長さを表します。

この機能はテキスト処理の多くの面で役立ちます。

例えば、ユーザー入力が期待される形式であるかを確認したり、文書内でキーワードを見つけてその位置をハイライトしたり、特定のパターンを置換する際など、多様なシチュエーションで有効活用することが可能です。

○サンプルコード1:文字列内の単語検索

Objective-CでrangeOfStringを使用して特定の単語が文字列内に存在するかどうかを調べる一般的な方法を見てみましょう。

下記のコードスニペットは、”Hello, World!”の中から”World”という単語を検索する一例を表しています。

NSString *originalString = @"Hello, World!";
NSString *wordToSearch = @"World";
NSRange searchResult = [originalString rangeOfString:wordToSearch];

if (searchResult.location != NSNotFound) {
    NSLog(@"'%@'が位置%dで見つかりました。", wordToSearch, (int)searchResult.location);
} else {
    NSLog(@"'%@'は見つかりませんでした。", wordToSearch);
}

このコードではNSStringのメソッドrangeOfString:を使用しています。

この例では”World”という単語が”Hello, World!”という文字列内で位置11で始まることを確認しています。

NSNotFoundは文字列が見つからなかった場合にrangeOfString:メソッドが返す値で、NSRange構造体のlocationプロパティがこれに等しいかどうかをチェックすることで、検索の有無を判断しています。

このコードを実行すると、コンソールに次のような出力結果が得られます。

'World'が位置11で見つかりました。

○サンプルコード2:大文字と小文字を区別しない検索

次に、大文字と小文字を区別せずに検索する方法について考えてみましょう。

これは、インターネットの検索や文書編集時に非常に役立つ機能です。

Objective-CではrangeOfString:options:メソッドを用いて、検索オプションを指定することでこれを実現できます。

ここではNSCaseInsensitiveSearchオプションを使うことで大文字小文字を区別せずに検索を行う例を紹介します。

NSString *originalString = @"Hello, World!";
NSString *wordToSearch = @"world";
NSRange searchResult = [originalString rangeOfString:wordToSearch options:NSCaseInsensitiveSearch];

if (searchResult.location != NSNotFound) {
    NSLog(@"大文字小文字を区別せずに'%@'が位置%dで見つかりました。", wordToSearch, (int)searchResult.location);
} else {
    NSLog(@"大文字小文字を区別せずに'%@'は見つかりませんでした。", wordToSearch);
}

このコードでは、optionsパラメータにNSCaseInsensitiveSearchを指定しています。

このオプションのおかげで、検索は”world”という単語を大文字小文字を問わずに”Hello, World!”から見つけ出すことができます。

もし検索する単語が文字列内に存在しなければ、locationプロパティはNSNotFoundを返し、その結果がログに出力されます。

○サンプルコード3:部分文字列が存在するかの確認

Objective-Cにおいて、ある文字列が別の文字列内に存在するかどうかを判定するためには、rangeOfStringメソッドを使用します。

下記のコードでは、@"Hello, World!"という文字列内に@"World"という部分文字列が存在するかどうかを確認しています。

NSString *fullString = @"Hello, World!";
NSString *searchString = @"World";

NSRange range = [fullString rangeOfString:searchString];

if (range.location != NSNotFound) {
    NSLog(@"部分文字列が見つかりました。");
} else {
    NSLog(@"部分文字列が見つかりませんでした。");
}

このコードではrangeOfStringを使って@"World"@"Hello, World!"の中で検索しています。

range.location != NSNotFoundを用いて部分文字列が存在するかの確認を行い、存在する場合はログにその旨を出力しています。

実行すると「部分文字列が見つかりました。」とコンソールに表示されます。

○サンプルコード4:文字列内の複数の範囲を検索

時には同じ文字列内で特定の部分文字列が複数存在するかもしれません。

そのような場合、rangeOfStringメソッドとループ構造を組み合わせて全ての出現箇所を見つけることができます。

下記のサンプルコードは、@"l"@"Hello, World! Love programming!"にいくつ含まれているか、またその位置を表しています。

NSString *fullString = @"Hello, World! Love programming!";
NSString *searchString = @"l";
NSRange searchRange = NSMakeRange(0, [fullString length]);
NSRange foundRange;

while(searchRange.location < fullString.length) {
    foundRange = [fullString rangeOfString:searchString options:0 range:searchRange];
    if (foundRange.location != NSNotFound) {
        // 部分文字列を見つけたら、次はその部分文字列の後ろから検索を続ける
        NSLog(@"'l'が見つかった位置: %lu", (unsigned long)foundRange.location);
        searchRange.location = foundRange.location + foundRange.length;
        searchRange.length = fullString.length - searchRange.location;
    } else {
        // 見つからなければループを抜ける
        break;
    }
}

このコードはwhileループを使って@"l"の各出現を検索し、見つかるごとに検索範囲を更新しています。

結果として、@"l"が見つかる位置がコンソールに出力されます。

○サンプルコード5:文字列置換にrangeOfStringを使用

文字列置換はプログラミングにおいても一般的な操作です。

Objective-Cでは、置換したい文字列を見つけた後、stringByReplacingCharactersInRange:withString:メソッドを使用して新しい文字列に置換します。

下記のサンプルではrangeOfStringを使って特定の文字列の位置を見つけ、それを別の文字列で置換しています。

NSString *originalString = @"Hello, World!";
NSString *stringToReplace = @"World";
NSString *replacementString = @"Objective-C";

NSRange range = [originalString rangeOfString:stringToReplace];

if (range.location != NSNotFound) {
    NSString *replacedString = [originalString stringByReplacingCharactersInRange:range withString:replacementString];
    NSLog(@"置換後の文字列: %@", replacedString);
} else {
    NSLog(@"置換する文字列が見つかりませんでした。");
}

このコードでは、originalStringの中からstringToReplaceに該当する部分をreplacementStringで置換しています。

rangeOfStringメソッドでstringToReplacerangeを取得し、stringByReplacingCharactersInRange:withString:で置換を行なっています。

コードを実行すると、「置換後の文字列: Hello, Objective-C」と表示されます。

●rangeOfStringの応用例

Objective-CにおけるrangeOfStringメソッドは、文字列処理の中核を成す非常に強力なツールです。

文字列の検索、データ検証、入力のフォーマットなど、幅広い場面でその効力を発揮します。

ここでは、rangeOfStringメソッドの応用例をいくつか紹介し、プログラムにおけるその利用方法を深堀りしていきます。

○サンプルコード1:ユーザー入力の検証

ユーザーがフォームに入力した電話番号が適切なフォーマットであるかを確認する際にrangeOfStringを使用することができます。

下記のコードは、ユーザーが入力した文字列にハイフンが含まれているかどうかを検証し、ハイフンの位置も正しいことを確認しています。

NSString *userInput = @"090-1234-5678"; // ユーザー入力値
NSString *pattern = @"[0-9]{3}-[0-9]{4}-[0-9]{4}"; // 正しい電話番号のパターン

NSRange range = [userInput rangeOfString:pattern options:NSRegularExpressionSearch];
if (range.location != NSNotFound) {
    NSLog(@"正しい電話番号の形式です。");
} else {
    NSLog(@"電話番号の形式が正しくありません。");
}

このコードではNSRegularExpressionSearchオプションを使って、正規表現を用いた検索を行っています。

パターンとして定義された正規表現が、ユーザー入力値にマッチすれば、「正しい電話番号の形式です。」と出力されます。

一方でマッチしなければ、「電話番号の形式が正しくありません。」と警告を出します。

この検証処理を実行すると、正しいフォーマットの入力には正の確認結果を、不正なフォーマットの場合は否定的な結果を返すことになります。

つまり、入力された電話番号が正規表現に合致するかどうかを効率的に確認することが可能です。

○サンプルコード2:検索結果のハイライト表示

ウェブページやドキュメント内でユーザーが検索したキーワードをハイライトする機能は、ユーザーエクスペリエンスの向上に非常に有効です。

下記のサンプルコードは、検索文字列を見つけ、その部分の背景色を変更してハイライトする方法を表しています。

NSString *fullText = @"ここはObjective-Cのプログラミングを学ぶブログです。";
NSString *searchKeyword = @"Objective-C";
NSString *replacement = [NSString stringWithFormat:@"<mark>%@</mark>", searchKeyword];

NSRange searchRange = [fullText rangeOfString:searchKeyword];
if (searchRange.location != NSNotFound) {
    NSString *highlightedText = [fullText stringByReplacingCharactersInRange:searchRange withString:replacement];
    NSLog(@"ハイライトされたテキスト: %@", highlightedText);
} else {
    NSLog(@"キーワードが見つかりませんでした。");
}

このコードではrangeOfStringメソッドを用いてsearchKeywordfullText内に存在するか確認しています。

キーワードが存在すれば、その部分を<mark>タグで囲んでハイライトし、存在しなければ対応するログを出力します。

こうすることで、ユーザーが検索した単語を視覚的に目立たせることができます。

この機能を実装すると、検索されたキーワードが文中でどのようにハイライトされるかを確認することができ、ユーザーは情報を素早く見つけることができるようになります。

○サンプルコード3:正規表現を使った高度な検索

Objective-Cでは、正規表現を使って複雑な文字列パターンの検索を行うことが可能です。

たとえば、下記のサンプルコードは、特定のパターンに一致するメールアドレスが文字列内に含まれているかどうかを確認するものです。

NSString *documentText = @"お問い合わせは[email protected]まで。";
NSString *emailRegex = @"[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}";

NSRange range = [documentText rangeOfString:emailRegex options:NSRegularExpressionSearch | NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
    NSLog(@"メールアドレスが見つかりました: %@", [documentText substringWithRange:range]);
} else {
    NSLog(@"メールアドレスが見つかりませんでした。");
}

この例では、NSRegularExpressionSearchNSCaseInsensitiveSearchのオプションを指定して、大文字小文字を区別せずにメールアドレス形式に合致する文字列を検索しています。

検索が成功すると、対象のメールアドレスがログに出力されます。

これにより、メールアドレスの検出や検証が容易になります。

●注意点と対処法

Objective-Cでの文字列検索は、パワフルながらも複雑な操作が発生することがあるため、いくつかの注意点を理解しておく必要があります。

まず最も重要なのは、rangeOfStringメソッドを使用する際に正確な検索パターンを指定することです。

間違ったパターンや不適切な検索オプションを指定すると、期待している結果が得られなかったり、プログラムがクラッシュする原因になり得ます。

また、大文字と小文字を区別するかどうか、ロケールに基づいた比較を行うかなど、検索条件の設定に細心の注意を払う必要があります。

○エラーハンドリングの重要性

Objective-Cにおけるエラーハンドリングは、安定したアプリケーション開発のために不可欠です。

rangeOfStringメソッドを使って文字列検索を行う際、検索対象の文字列がnullや空である場合、あるいは検索文字列が適切でない場合にエラーが発生することがあります。

これらの状況を事前にチェックし、適切なエラーメッセージを表示することで、ユーザーにとってより親切なアプリケーションになります。

例えば、下記のサンプルコードは、Objective-Cで文字列検索を行い、エラーを適切に処理する方法を表しています。

NSString *originalString = @"This is the string to search within.";
NSString *searchString = @"search";

// 文字列検索
NSRange searchRange = [originalString rangeOfString:searchString];

// 検索結果の確認とエラーハンドリング
if (searchRange.location == NSNotFound) {
    NSLog(@"検索文字列が見つかりませんでした。");
} else {
    NSLog(@"検索文字列が見つかりました。位置: %lu, 長さ: %lu", (unsigned long)searchRange.location, (unsigned long)searchRange.length);
}

このコードでは、まずoriginalString内でsearchStringを検索しています。

検索結果はNSRange構造体に格納され、locationとlengthプロパティで位置と長さを確認できます。

NSNotFoundが返された場合は、検索文字列が見つからなかったことをログに記録しています。

この処理により、検索が失敗した原因を追跡しやすくなります。

○検索性能の最適化

検索処理のパフォーマンスを最適化するには、複数のテクニックが有効です。

例えば、検索対象のデータサイズを小さく保つ、適切なインデックスを使用する、非同期処理を活用する、などの方法があります。

また、頻繁に行われる検索処理の場合は、検索結果をキャッシュすることで、次回の検索時にパフォーマンスを向上させることができます。

検索の最適化には、次のようなコードを考えることができます。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // バックグラウンドスレッドでの検索処理
    NSRange searchRange = [originalString rangeOfString:searchString];

    dispatch_async(dispatch_get_main_queue(), ^{
        // メインスレッドでのUI更新処理
        if (searchRange.location != NSNotFound) {
            // 検索結果をUIに反映するなどの処理
        }
    });
});

この例では、Grand Central Dispatch(GCD)を使用してバックグラウンドスレッドで検索処理を行い、その後メインスレッドでUIを更新しています。

このようにすることで、検索処理によるUIの反応の遅れを防ぐことができます。

●カスタマイズ方法

プログラミングにおいて、カスタマイズは非常に重要な要素です。

カスタマイズによって、標準的な機能を超えて、ユーザーの特定のニーズに合わせたアプリケーションを作成できます。

Objective-Cでの文字列検索では、rangeOfStringメソッドを使いながら、検索オプションをカスタマイズして、より高度な検索機能を実現することが可能です。

カスタマイズの範囲は広く、検索条件の変更、検索アルゴリズムの最適化、さらには独自の検索パターンの実装まで含まれます。

○検索オプションのカスタマイズ

Objective-Cにおいて、検索オプションのカスタマイズは、検索メソッドの引数を変更することで行います。

例えば、case-insensitive(大文字と小文字を区別しない)検索や、ロケールに依存する検索など、様々なオプションを設定することができます。

このようなカスタマイズは、NSComparisonOptions列挙型を用いて実施されます。

下記のサンプルコードは、case-insensitive検索のカスタマイズを表しています。

このコードではNSStringクラスのrangeOfString:options:メソッドを使用し、大文字と小文字を区別せずに文字列を検索しています。

NSCaseInsensitiveSearchオプションを指定することで、この挙動を実現しています。

NSString *originalString = @"Hello World";
NSString *searchString = @"world";
NSRange searchRange = [originalString rangeOfString:searchString options:NSCaseInsensitiveSearch];

if (searchRange.location != NSNotFound) {
    NSLog(@"検索した文字列 '%@' は位置 %lu で見つかりました。", searchString, (unsigned long)searchRange.location);
} else {
    NSLog(@"検索した文字列 '%@' は見つかりませんでした。", searchString);
}

このコードを実行すると、’world’という文字列が’Hello World’の中に存在するかどうかを大文字小文字を区別せずに検索し、見つかった場合にはその位置をコンソールに出力します。

この例では、’world’は’Hello World’の7番目の位置で見つかります。

○独自の検索機能の開発

Objective-Cでより独自性の高い検索機能を開発する場合、正規表現や文字列解析のライブラリを利用することができます。

NSRegularExpressionクラスは、文字列内で複雑な検索や置換を行うための強力な手段を提供しており、特定のパターンに一致する文字列の検索に適しています。

例として、下記のコードは正規表現を使って特定のパターンにマッチする文字列を検索する方法を表しています。

ここでは、メールアドレスの形式に一致する文字列を検索しています。

NSString *stringToSearch = @"My email is [email&nbsp;protected] and I use it frequently.";
NSString *emailRegex = @"[A-Z0-9a-z._%+-][email&nbsp;protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,6}";
NSError *error = nil;

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:emailRegex
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:&error];
if (error) {
    NSLog(@"正規表現の作成中にエラーが発生しました: %@", error.localizedDescription);
} else {
    NSTextCheckingResult *firstMatch = [regex firstMatchInString:stringToSearch
                                                         options:0
                                                           range:NSMakeRange(0, [stringToSearch length])];
    if (firstMatch) {
        NSRange matchRange = [firstMatch range];
        NSString *matchedString = [stringToSearch substringWithRange:matchRange];
        NSLog(@"メールアドレスの一致: %@", matchedString);
    } else {
        NSLog(@"メールアドレスのパターンに一致する文字列は見つかりませんでした。");
    }
}

このコードを実行すると、指定したメールアドレスの形式に一致する最初の文字列を検索し、見つかった場合にはその文字列を出力します。

この例では、「[email protected]」が一致し、コンソールにその結果が表示されます。

まとめ

Objective-Cにおける文字列検索の方法は多岐にわたりますが、この記事では、rangeOfStringメソッドを中心にした5つの異なるアプローチを解説しました。

rangeOfStringメソッドは、指定された文字列が対象の文字列内に存在するかどうか、またその位置を知るための基本的なメソッドです。

プログラミング初心者でも理解しやすいように、基本的な使用法から応用例、注意点と対処法まで、実際のサンプルコードを用いて段階的に解説しました。

今回解説した内容を踏まえ、Objective-Cでの文字列検索技術は、適切なメソッドとパラメータを理解し選択することにより、効率的かつ効果的な検索が可能となります。

rangeOfStringの使い方をマスターすることで、Objective-Cのプログラミングスキルを大きく向上させることができるでしょう。