読み込み中...

Pythonにおけるfindメソッドを使った文字列検索の実例14選

Pythonのfindメソッドを学ぶ初心者向けイラスト Python
この記事は約28分で読めます。

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

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

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

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

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

Pythonのfind()メソッドは、文字列の中から指定した部分文字列を探し、最初に見つかった位置をintで返す文字列検索の手段です。見つからない場合は-1になるため、条件分岐と組み合わせると、ログ解析、入力チェック、データ整形、簡単なスクリプトの判定処理まで扱えます。

公式ドキュメントによれば、str.find()startendを任意で受け取り、スライス範囲に近い考え方で検索範囲を絞れます。正規表現が必要な場面ではre.search()を使い、単純なキーワード判定ではin演算子やfind()を選ぶと、コーディングの意図が読み取りやすくなるのが基本です。

動作確認環境
  • Python 3.12
  • pandas 2.2 / requests 2.31 / NLTK 3.8
📖 この記事で学べること
  • find()の戻り値と-1判定の扱い方
  • startendrfind()を使った検索範囲の調整
  • 文字列検索をファイル、リスト、ログ、データ分析へ広げる考え方
  • TypeErrorAttributeErrorを避ける入力チェック
  • 正規表現、スクレイピング、AI処理と組み合わせる判断軸

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

Pythonのfindメソッドとは?

Pythonで単純な文字列検索を行うなら、strオブジェクトに備わるfind()メソッドが候補になります。公式のPython標準型ドキュメントでは、部分文字列が見つかった位置を返し、見つからなければ-1を返すメソッドとして説明されています。

この戻り値の性質により、if position != -1のような条件分岐を書けるのが目安です。そのため、単に含まれるかを調べるだけでなく、どの位置から切り出すかを決めるアルゴリズムにもつなげられます。

Pythonでの文字列操作の基本

Pythonでは文字列をstr型として扱い、"Hello"'Hello'のようにリテラルで作れます。このstrにはlen()split()replace()strip()lower()などの操作がまとまっており、プログラミングの初期段階から頻繁に使いるのがポイントです。

その中でfind()は、文字そのものを変更せず、検索した位置だけを返すメソッドです。一方、replace()は置換後の新しい文字列を返すため、文字列検索と文字列変換を分けて考えるとコーディングの読み違いを減らせます。

一般に、存在確認だけなら"Python" in textが読みやすく、位置が必要ならtext.find("Python")が適しています。その使い分けを押さえると、スクリプトの条件式が短くなり、後から読む人にも意図が伝わりやすくなるのが一般的です。

用途主な書き方戻り値向いている場面
位置検索text.find("x")位置または-1切り出し開始位置が必要な処理
存在確認"x" in textTrueまたはFalse分岐だけで足りる処理
末尾側検索text.rfind("x")位置または-1拡張子や最後の区切りを探す処理
例外で判定text.index("x")位置またはValueError見つからない状態を例外として扱う処理
正規表現検索re.search(pattern, text)MatchまたはNone桁数や形式を含む複雑な検索

findメソッドの文法とパラメータ

find()の基本形はstring.find(substring, start, end)です。substringは検索したい文字列、startは検索開始位置、endは検索終了位置を表し、startendは省略できます。

このとき、endの位置そのものは検索範囲に含まれない点に注意します。text[0:5]のようなスライスと同じ感覚で読むと、文字列検索の範囲指定を誤りにくくなるのが現実的です。

💡 Tips: find()は大文字と小文字を区別します。大小を無視したい場合は、検索対象とキーワードの両方へlower()またはcasefold()を適用します。

ただし、find()は単純な部分一致に向いたメソッドです。桁数、任意文字、繰り返し、行頭などの条件を含む場合は、Pythonのreモジュール公式ドキュメントにあるre.search()re.finditer()を検討すると整理しやすくなると整理できます。

Pythonの基礎を広く確認したい場合は、Python初心者のための完全ガイド!アプリ化の10ステップも合わせて読むと、文字列処理とアプリ化の関係をつかみやすくなります。

findメソッドを使った具体的な例

findメソッドは短いコードでも動きが読み取りやすく、文字列検索の学習に向いています。各サンプルでは、positionsubstringstartなどの変数がどの役割を持つかに注目すると、コーディング時のミスを減らせますし、ここがポイントです。

サンプルコード1:単語の位置を見つける

文章の中から単語の位置を得る基本形です。

text = "Python is an easy to learn, powerful programming language."
word = "powerful"
position = text.find(word)
print(f"The word '{word}' is found at index {position}.")

結果: 期待される出力は、検索語powerfulの開始位置を示す文です。find()の戻り値をpositionへ入れる流れを確認できます。

The word 'powerful' is found at index 26.

結果: 期待される出力例はindex 26を含む1行です。文字列検索では、先頭の文字を0として数えます。

このコードでは、textに対象文、wordに探す単語を置いていると理解できます。そのため、検索語を変えるだけで同じスクリプトを別の単語にも使えます。

サンプルコード2:サブストリングが見つからない場合の処理

-1を分岐条件に使う例です。

text = "Python is an easy to learn, powerful programming language."
substring = "java"
position = text.find(substring)
if position == -1:
    print(f"The substring '{substring}' is not found in the text.")
else:
    print(f"The substring '{substring}' is found at index {position}.")

結果: 期待される出力は、javaが見つからないことを示す文です。position == -1を使うと、未検出時の処理を明示できます。

The substring 'java' is not found in the text.

結果: 期待される出力例は未検出を表す1行です。PythonとJavaの表記差も、文字列検索では単なる文字の違いとして扱われます。

そのため、ifelseを組み合わせると、ユーザーへ返すメッセージを分けられますが、これは押さえたい点です。プログラミングでは未検出を正常系として扱う設計もよく使われます。

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

lower()を挟んで大小文字の差を吸収します。

text = "Python is an easy to learn, powerful programming language."
substring = "python"
position = text.lower().find(substring.lower())
if position != -1:
    print(f"The substring '{substring}' is found at index {position} (case-insensitive).")
else:
    print(f"The substring '{substring}' is not found in the text (case-insensitive).")

結果: 期待される出力は、pythonが位置0で見つかることを示します。変換後の文字列で検索するため、表示用の元文字列は別に保持すると扱いやすくなります。

The substring 'python' is found at index 0 (case-insensitive).

結果: 期待される出力例は大小文字を無視した検索結果です。lower()は英字中心の比較でよく使われますし、これが一つの目安です。

一方、多言語文字列まで考えるならcasefold()の検討余地があります。単純な英語ログや設定値ではlower()でも十分な場面が多いです。

サンプルコード4:文字列内のすべての出現を見つける方法

複数回出現する語をwhileで追跡します。

text = "Python is an easy to learn, powerful programming language. Python is often used for web development, data analysis, artificial intelligence, and more."
substring = "Python"

positions = []
start = 0
while True:
    position = text.find(substring, start)
    if position == -1:
        break
    positions.append(position)
    start = position + 1

if positions:
    print(f"The substring '{substring}' is found at positions: {positions}")
else:
    print(f"The substring '{substring}' is not found in the text.")

結果: 期待される出力は、Pythonの出現位置をリストで示す文です。startを更新しないと同じ位置を探し続けるため、ループの進行条件が要点になります。

The substring 'Python' is found at positions: [0, 92]

結果: 期待される出力例は[0, 92]です。positions.append(position)により、見つかった順に位置を蓄積します。

このアルゴリズムは、重複を許す検索にも応用できると覚えるとよいでしょう。ただし、検索語の長さぶん進めるか、1文字ずつ進めるかで重なりの扱いが変わります。

サンプルコード5:テキストファイル内の文字列検索

open()read()で読み込んだ内容に検索をかけます。

with open("sample.txt", "r", encoding="utf-8") as file:
    content = file.read()
    substring = "Python"
    position = content.find(substring)
    if position != -1:
        print(f"The substring '{substring}' is found in the file at index {position}.")
    else:
        print(f"The substring '{substring}' is not found in the file.")

結果: 期待される出力は、sample.txtの内容に依存します。encoding="utf-8"を明示すると、日本語を含むファイルでも読み込み方をそろえやすくなります。

The substring 'Python' is found in the file at index 10.

結果: 期待される出力例は、ファイル内のPythonが位置10にある場合の表示です。実際の位置はファイルの内容で変わりますが、覚えておくと役立つでしょう。

そのため、外部ファイルを扱うスクリプトでは、入力データの前提をコメントや設定に残すと保守しやすくなります。大きなファイルではfor line in fileによる行単位処理も候補です。

サンプルコード6:リスト内の文字列の検索

forでリストの各要素を調べます。

strings = ["apple", "banana", "cherry", "date", "elderberry"]
substring = "er"
for string in strings:
    if string.find(substring) != -1:
        print(f"The substring '{substring}' is found in '{string}'.")
    else:
        print(f"The substring '{substring}' is not found in '{string}'.")

結果: 期待される出力は、各単語にerが含まれるかを1行ずつ示すると考えられます。リスト処理と文字列検索を組み合わせる基本形です。

The substring 'er' is not found in 'apple'.
The substring 'er' is not found in 'banana'.
The substring 'er' is found in 'cherry'.
The substring 'er' is not found in 'date'.
The substring 'er' is found in 'elderberry'.

結果: 期待される出力例では、cherryelderberryだけが一致します。for文により、同じ判定を各要素へ適用できます。

これをlist内包表記に変えると、一致した単語だけを集める書き方にもできると言えるでしょう。読みやすさを優先する場面では、明示的なfor文のほうが扱いやすいでしょう。

サンプルコード7:文字列の先頭と末尾からの検索

find()rfind()を比べます。

text = "This is a sample text."
first_space = text.find(" ")
last_space = text.rfind(" ")
print(f"The first space is found at index {first_space}.")
print(f"The last space is found at index {last_space}.")

結果: 期待される出力は、最初の空白と最後の空白の位置です。rfind()は末尾側から探し、見つかった位置は先頭から数えたインデックスで返します。

The first space is found at index 4.
The last space is found at index 15.

結果: 期待される出力例は415です。最後の区切り文字を探す処理ではrfind()が短く書けるのが基本です。

この考え方は、ファイル名から拡張子の直前を探す処理にもつながります。ただし、パス処理ではpathlibのような専用APIを使うほうが堅実です。

サンプルコード8:複数の異なるサブストリングを検索

検索語をリストにまとめ、同じ処理を回します。

text = "Python is an easy to learn, powerful programming language."
substrings = ["easy", "powerful", "programming"]
for substring in substrings:
    position = text.find(substring)
    if position != -1:
        print(f"The substring '{substring}' is found at index {position}.")
    else:
        print(f"The substring '{substring}' is not found in the text.")

結果: 期待される出力は、各キーワードの位置です。検索語をsubstringsに分けると、条件追加時の変更範囲を小さくできます。

The substring 'easy' is found at index 12.
The substring 'powerful' is found at index 26.
The substring 'programming' is found at index 36.

結果: 期待される出力例は3行です。複数キーワードの文字列検索では、結果をdictへ保存する形にも発展できます。

同様に、設定ファイルから検索語を読み込めば、スクリプトの再利用範囲が広がりますし、ここを基本と考えるとよいでしょう。検索語が増える場合は、正規表現や全文検索の採用も検討対象になります。

サンプルコード9:正規表現とfindメソッドの組み合わせ

金額のような形式付き文字列はre.search()が向いています。

import re

text = "The price is $10.50."
pattern = r"$d+.d+"
match = re.search(pattern, text)
if match:
    start = match.start()
    end = match.end()
    print(f"The price is found at index {start} to {end - 1}.")
else:
    print("No price found in the text.")

結果: 期待される出力は、金額表記が見つかった範囲です。find()ではなくre.search()を使うことで、数字の桁数が変わっても検索できます。

The price is found at index 13 to 18.

結果: 期待される出力例は13から18までの範囲です。match.start()match.end()で位置情報を取得できます。

ただし、固定文字列だけを探すなら正規表現は過剰になることがあるのが目安です。文字列検索の条件が単純か複雑かで、find()reを使い分けるとよいでしょう。

サンプルコード10:エラーハンドリングと検索の最適化

tryと型の前提を含めた関数化の例です。

def search_substring(text, substring):
    try:
        if substring in text:
            position = text.find(substring)
            print(f"The substring '{substring}' is found at index {position}.")
        else:
            print(f"The substring '{substring}' is not found in the text.")
    except TypeError:
        print("Invalid input. Please provide strings for both text and substring.")

# 使用例
search_substring("Hello, world!", "world")
search_substring("Hello, world!", "python")
search_substring(42, "hello")

結果: 期待される出力は、一致、未一致、型エラーの3種類です。in演算子で存在確認を行い、位置が必要なときだけfind()を呼び出しています。

The substring 'world' is found at index 7.
The substring 'python' is not found in the text.
Invalid input. Please provide strings for both text and substring.

結果: 期待される出力例は3行です。TypeErrorを捕捉することで、文字列ではない値が渡った場合にも処理を止めずに案内できます。

一方、業務用の関数では、例外を握りつぶさず呼び出し元へ返す設計もあるのがポイントです。学習用スクリプトでは表示、ライブラリ用コードでは例外や戻り値で伝える、と分けると整理できます。

表計算やグラフ処理へ進む場合は、文字列検索で抽出した値をデータ加工へ渡す流れも出てきます。Pythonでの可視化に関心がある場合は、Pythonで折れ線グラフ作成の完全ガイド10選のようなデータ処理系の記事も役立ちますし、ここがポイントです。

よくあるエラーと対処法

findメソッドのエラーは、引数の数、対象オブジェクトの型、index()との混同で起きやすくなります。初心者がつまずきやすいのは、find()が未検出時に例外ではなく-1を返す点と、intNoneにはfind()がない点です。

⚠️ 注意: find()index()は似ていますが、未検出時の動きが違います。find()-1index()ValueErrorです。

TypeError: find() takes at most 3 arguments (4 given)

このエラーは、find()へ余分な引数を渡したときに発生するのが一般的です。受け取れるのは検索語、開始位置、終了位置までなので、条件を増やしたい場合は事前に別の変数で整理します。

text = "Hello, world!"
substring = "world"
start = 0
end = len(text)
position = text.find(substring, start, end)  # 正しい引数の数

結果: 期待される動きは、position7が入ることです。表示が必要な場合は、この後にprint(position)を追加します。

AttributeError: ‘int’ object has no attribute ‘find’

このエラーは、数値へfind()を呼び出したときに発生するのが現実的です。文字列検索をしたいなら、対象をstr()で文字列化するか、最初から文字列として受け取る設計にします。

number = 42
position = str(number).find("4")  # 整数を文字列に変換

結果: 期待される動きは、position0が入ることです。str(number)により、42"42"として扱われます。

ValueError: substring not found

この例外はfind()ではなく、主にindex()で未検出だった場合に発生すると整理できます。find()を使うなら-1判定、index()を使うならtryexceptで分岐します。

text = "Hello, world!"
substring = "python"
try:
    position = text.find(substring)
    print(f"The substring '{substring}' is found at index {position}.")
except ValueError:
    print(f"The substring '{substring}' is not found in the text.")

結果: 期待される出力は、find()の戻り値-1を含む文です。このコードではValueErrorは通常発生しないため、未検出処理としてはif position == -1のほうが自然です。

そのため、未検出を例外として扱いたい設計ならindex()、通常の分岐として扱いたい設計ならfind()を選びます。フォーム入力やログ監視のように未検出がよくある処理では、-1判定のほうが流れを追いやすい場合があります。

同様に、画面操作や自動化処理の中で検索結果を使う場合は、見つからなかった状態を必ず分岐させますが、これは押さえたい点です。Pythonでウィンドウ操作を自動化する例は、Pythonで実現!ウィンドウ操作の自動化15選とも関連します。

findメソッドの応用例

findメソッドの応用は、HTML、CSV、ログ、自然言語テキストなど、文字として読めるデータ全般に広がります。単純な文字列検索で十分な場面と、専用ライブラリや別のアルゴリズムへ切り替える場面を分けると、スクリプトの構成が明確になると理解できます。

サンプルコード11:Webスクレイピングでの利用

HTML文字列の中からキーワードを探す例です。

import requests

url = "https://example.com"
response = requests.get(url)
html_content = response.text

keyword = "Python"
if keyword in html_content:
    position = html_content.find(keyword)
    surrounding_text = html_content[position - 20:position + 20]
    print(f"The keyword '{keyword}' is found in the HTML content.")
    print(f"Surrounding text: ...{surrounding_text}...")
else:
    print(f"The keyword '{keyword}' is not found in the HTML content.")

結果: 期待される出力は、HTML内にキーワードがある場合の周辺文字列です。実際の表示は取得先ページの内容と通信状態で変わります。

The keyword 'Python' is found in the HTML content.
Surrounding text: ...earning <strong>Python</strong> programming...

結果: 期待される出力例は、Python周辺のHTML断片を含む2行です。実際のWebページではタグ構造が変わるため、固定位置への依存は避けます。

ただし、HTMLの解析にはBeautifulSouplxmlのほうが適する場面があると覚えるとよいでしょう。find()は、取得済みテキスト内のキーワード位置を軽く確認する用途に向いています。

サンプルコード12:データ分析でのテキスト処理

pandasDataFrameに検索結果を追加します。

import pandas as pd

data = [
    {"id": 1, "text": "Python is a versatile language."},
    {"id": 2, "text": "It is easy to learn Python."},
    {"id": 3, "text": "Python has a large community."},
    {"id": 4, "text": "I enjoy coding in Python."}
]

df = pd.DataFrame(data)

keyword = "Python"
df["contains_keyword"] = df["text"].apply(lambda x: keyword in x)
df["keyword_position"] = df["text"].apply(lambda x: x.find(keyword))

print(df)

結果: 期待される出力は、contains_keywordkeyword_positionを持つ表です。apply()で各行の文字列へ同じ処理を適用します。

   id                              text  contains_keyword  keyword_position
0   1    Python is a versatile language.              True                 0
1   2       It is easy to learn Python.              True                18
2   3    Python has a large community.              True                 0
3   4         I enjoy coding in Python.              True                16

結果: 期待される出力例では、すべての行にPythonが含まれています。位置情報を列として持つと、後続の集計やフィルタリングへ渡せます。

一方、大規模データではSeries.str.contains()Series.str.find()のほうが書きやすい場合があると考えられます。表操作の基礎は、初心者必見!Pythonで表を操作するための7つの詳細ガイドともつながります。

サンプルコード13:自動化スクリプトでの活用

ログファイルからERROR行を抜き出します。

log_file = "application.log"
error_keyword = "ERROR"

with open(log_file, "r") as file:
    for line in file:
        if error_keyword in line:
            error_position = line.find(error_keyword)
            error_message = line[error_position:].strip()
            print(f"Error found: {error_message}")

結果: 期待される出力は、ERRORを含む行の抽出結果です。実際の表示はapplication.logの内容で変わります。

Error found: ERROR: Division by zero
Error found: ERROR: File not found

結果: 期待される出力例は、エラー行だけを取り出した2行です。strip()で改行を取り除くため、ログの表示が整います。

こうした自動化スクリプトでは、検出語を設定ファイル化すると運用しやすくなると言えるでしょう。改行ありの表示や出力制御を調整したい場合は、Pythonで改行あり・なしを制御する方法と応用例10選も参考になります。

サンプルコード14:AIとの組み合わせ

自然言語処理の前処理として、対象語を含む文だけを分析します。

import nltk
from nltk.sentiment import SentimentIntensityAnalyzer

text = "Python is a great programming language. It is easy to learn and has a wide range of applications. However, sometimes it can be slow compared to compiled languages."

sentences = nltk.sent_tokenize(text)
sia = SentimentIntensityAnalyzer()

for sentence in sentences:
    if "Python" in sentence:
        sentiment_scores = sia.polarity_scores(sentence)
        print(f"Sentence: {sentence}")
        print(f"Sentiment scores: {sentiment_scores}")
        print()

結果: 期待される出力は、Pythonを含む文と感情スコアです。NLTKのデータセットが未導入の場合は、別途ダウンロードが必要になる場合があります。

Sentence: Python is a great programming language.
Sentiment scores: {'neg': 0.0, 'neu': 0.508, 'pos': 0.492, 'compound': 0.6249}

Sentence: However, sometimes it can be slow compared to compiled languages.
Sentiment scores: {'neg': 0.13, 'neu': 0.87, 'pos': 0.0, 'compound': -0.2263}

結果: 期待される出力例は、文とスコア辞書の組み合わせです。感情分析の値はライブラリや辞書データの状態により変わる可能性があります。

この応用では、find()そのものよりも、対象文を絞り込む前処理が役割になります。AIアルゴリズムへ渡す前に不要な文を減らすと、後続処理の見通しが良くなるのが基本です。

ℹ️ 補足: 文字列検索は、単体のテクニックではなく前処理の部品として使われます。検索、抽出、整形、保存の順に考えると、プログラミング全体の流れへ組み込みやすくなります。

具体的には、短いログならfind()、複雑な形式ならre、構造化されたHTMLならパーサ、表形式ならpandasの文字列アクセサを選びますし、これが一つの目安です。目的に合わせて道具を分けることで、コーディングの量と読みやすさのバランスを取りやすくなります。

まとめ

Pythonのfindメソッドは、文字列検索で最初に見つかった位置を返し、見つからなければ-1を返します。この単純な仕様を理解すると、入力値の検査、ファイル内検索、ログ抽出、データ分析の前処理まで、さまざまなスクリプトへ自然に組み込めますが、覚えておくと役立つでしょう。

そのため、存在確認だけならin、位置が必要ならfind()、未検出を例外で扱うならindex()、複雑なパターンならre.search()と整理できます。メソッドごとの戻り値をそろえて理解すると、文字列検索のアルゴリズムを組むときに条件分岐が明確になります。

ただし、find()は万能な解析器ではありません。HTML構造、自然言語、巨大なデータセットでは専用ライブラリと組み合わせ、単純なキーワード確認を担当させるのが現実的です。

これらの使い分けを押さえると、Pythonのプログラミングで文字列を扱う場面に対応しやすくなるのが目安です。短いコーディングから始め、ファイル、表、ログ、AI処理へ段階的に広げると、findメソッドの役割を実務的に理解できます。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。