■python備忘録 #2「pythonで文字列検索する際に〇〇+任意の文字列+△△でフィルタをかけるには?」

スポンサーリンク
tech系(python)
スポンサーリンク

すいません、タイトルではあまりうまく説明できなかったのですが、pythonである文字列に対してフィルターをかけることができるのですが、これをするときに「if in」を使う事(使い方は後述しています)になります。

ただ、任意文字に対して、例えば「This is a pen」、「This is my pen」、「Is this a pen?」という文字列があった時、「This is a pen」、「This is my pen」だけを抽出したいとすると、「if in」では難しいです。これはthisとisとpenという単語が含まれている文字列を抽出することはできますが、単語の順番は考慮できないからです。

こんな時はどうすればよいでしょうか。

結論から言うと正規表現を使います。

まずはpythonの「if in」の説明からしていく事にしていきましょう。。。

pythonの「if … in …. 」

始めに

今回は以下のようなリストを例に説明していきます。

sentence_list = [
    "Hello world",
    "This is a pen",
    "This is my pen",
    "This is a apple",
    "This is his apple",
    "apple pen",
    "I hava a pen",
    "I have an apple",
    "pe painappo appo pen",
    "pen pen This",
    "pen pen this",
    "this is a pen"
]

この文字列のリストから「this」から始まって「pen」で終わる文字列だけを抽出するとします。

なので、「This is a pen」と「This is my pen」と「this is a pen」を抽出できればOKです。

pythonの「if … in …. 」:penが含まれている文字列を抽出する

まず、pythonの「if in」を知るためにどんな使い方をするかを見ておきます。

「pen」という単語が含まれている文字列を抽出してみます。

fillter_words_1 = "pen"

for sentence_item in sentence_list: # 👈上記のsentence_listから一つずつ文字列を見ていく
    if fillter_words_1 in sentence_item: # 👈★「if in」の記述です
        print(sentence_item)

出力は以下のようになります。

This is a pen
This is my pen
apple pen
I hava a pen
pe painappo appo pen
pen pen This
pen pen this
this is a pen

pythonの「if … in …. 」で「this」から始まって「pen」で終わる文字列だけを抽出できるのか①

はい、ちょっとハマったところの共有としてpythonの「if … in …. 」で「this」から始まって「pen」で終わる文字列だけを抽出できるのかをやってみました。

結論から言うとできなかったです(笑)

ですので興味のない方は本題である後述の「正規表現を使った方法(解決策🕵️‍♀️)で解決」の章まで飛ばしてください。

さて、まず初めにやったこととしてはアスタリスク(*)を使ってできるのかという方法です。

ワイルドカードとして任意の文字列を指定するときによく使われるアスタリスク。

そのアスタリスクを使えば「this」から始まって「pen」で終わる文字列だけを抽出できるのではないのかと思ったわけです。

以下のようにコードを書きました。

fillter_words_2 = "This*pen" # 👈アスタリスクを使ってフィルタ用の文字列

for sentence_item in sentence_list:
    if fillter_words_2 in sentence_item:
        print(sentence_item)

出力は一切されませんでした。。結果は失敗です。

pythonの「if … in …. 」で「this」から始まって「pen」で終わる文字列だけを抽出できるのか②

ここでアスタリスク(*)が文字列として処理されてしまっている事を考えました。

このためエスケープをすればアスタリスクがアスタリスクとして認識されるんじゃないかと思ったわけです。

そこで以下のようにコードを書きました。

fillter_words_3 = "This\*pen" # 👈アスタリスクをエスケープできるんじゃないかと試したフィルタ用の文字列

for sentence_item in sentence_list:
    if fillter_words_3 in sentence_item:
        print(sentence_item)

出力は一切されませんでした。結果は失敗です。

ちなみに「this」と「pen」を含んでいる文字列は出力できる

ちなみに「this」と「pen」を含んでいる文字列といった感じで複数の単語を含んでいる文字列も抽出できます。

この場合は以下のような記述になります。

fillter_words_4 = ["This", "pen"] # 👈検索ワードが2個(複数)

for sentence_item in sentence_list:
    if all(x in sentence_item for x in fillter_words_4):
        print(sentence_item)

こうすると出力結果は以下のようになります。

This is a pen
This is my pen
pen pen This

検索対象の文字列たちが以下のようになっていたので(上記のを再掲)

sentence_list = [
    "Hello world",
    "This is a pen",
    "This is my pen",
    "This is a apple",
    "This is his apple",
    "apple pen",
    "I hava a pen",
    "I have an apple",
    "pe painappo appo pen",
    "pen pen This",
    "pen pen this",
    "this is a pen"
]

「this」と「pen」を含んでいる文字列のみが抽出できてますね。

正規表現を使った方法(解決策🕵️‍♀️)

はい、上記を踏まえて、「if … in …. 」では無理だったという訳です。

そこで解決策として出てくるのが正規表現です。

「this」から始まって「pen」で終わる文字列を正規表現で示すと以下ですね。

"this.*pen"

ですので、この正規表現をフィルターの値として用います。reをimportするのを忘れずに。

import re

re_fillter_words = "this.*pen"

for sentence_item in sentence_list:
    if (re.search(re_fillter_words, sentence_item.lower())):
    # 👆大文字と小文字を区別しないようにlowerで検索対象のものを小文字にしている
        print(sentence_item)

実行結果は以下のようになります。

This is a pen
This is my pen
this is a pen

まとめ

今回は「pythonで文字列検索する際に●● + 任意の文字列 + ▲▲でフィルタをかける」やり方について紹介しました。

要はpythonは特定の文字列を探すためにif文でinというものが使えますが、より具体的に検索条件を定めたい場合は正規表現を使ったら解決できるよって内容です。

上手く検索条件を絞れない時は正規表現を使ってみて下さい。

今回はここまで。最後まで読んでいただきありがとうございました。


タイトルとURLをコピーしました