Python:文字列内の部分文字列を検索し、部分文字列のインデックスを返します

2014年02月18日に質問されました。  ·  閲覧回数 194k回  ·  ソース

Tyler picture
2014年02月18日

私は持っています:

  • 関数: def find_str(s, char)

  • および文字列: "Happy Birthday"

私は基本的に入力したい"py"と返す3私は入れません2代わりに返すこと。

コード:

def find_str(s, char):
    index = 0           
    if char in s:
        char = char[0]
        for ch in s:
            if ch in s:
                index += 1
            if ch == char:
                return index

    else:
        return -1

print(find_str("Happy birthday", "py"))

何が悪いのかわからない!

回答

demented hedgehog picture
2014年02月18日
203

文字列オブジェクトには組み込みのメソッドfindがあります。

s = "Happy Birthday"
s2 = "py"

print(s.find(s2))

Pythonは「バッテリーを含む言語」であり、すでに必要なことのほとんど(必要なことは何でも)を実行するように記述されたコードがあります。これが宿題でない限り:)

文字列が見つからない場合、 findは-1を返します。

Eric Fortin picture
2014年02月18日
23

理想的には、痴呆ハリネズミが言ったように、

問題は、コードが検索文字列の最初の文字(最初の文字)がインデックス2にあるだけを検索することです。

基本的に、 char[0]sにある場合は、 index ch == char[0]までインクリメントすると、テスト時に3が返されますが、それでも間違っていました。 これを行う方法は次のとおりです。

def find_str(s, char):
    index = 0

    if char in s:
        c = char[0]
        for ch in s:
            if ch == c:
                if s[index:index+len(char)] == char:
                    return index

            index += 1

    return -1

print(find_str("Happy birthday", "py"))
print(find_str("Happy birthday", "rth"))
print(find_str("Happy birthday", "rh"))

次の出力が生成されました。

3
8
-1
zyy picture
2019年12月06日
3

正規表現にはもう1つのオプション、 searchメソッドがあります。

import re

string = 'Happy Birthday'
pattern = 'py'
print(re.search(pattern, string).span()) ## this prints starting and end indices
print(re.search(pattern, string).span()[0]) ## this does what you wanted

ちなみに、最初のパターンだけでなく、すべてのパターンの出現を検索したい場合は、 finditerメソッドを使用できます。

import re

string = 'i think that that that that student wrote there is not that right'
pattern = 'that'

print([match.start() for match in re.finditer(pattern, string)])

試合のすべての開始位置を印刷します。

Gerry picture
2019年06月14日
2

find()使用に関する@dementedハリネズミの回答に追加

効率の面で

find()呼び出す前に、s1がs2にあるかどうかを最初に確認することをお勧めします。
ほとんどの場合、s1がs2の部分文字列にならないことがわかっている場合、これはより効率的です。

in演算子は非常に効率的であるため

 s1 in s2

変換する方が効率的です。

index = s2.find(s1)

index = -1
if s1 in s2:
   index = s2.find(s1)

これは、 find()が-1を大量に返す場合に役立ちます。

アルゴリズムでfind()が何度も呼び出されていたので、かなり高速であることがわかりました。そのため、言及する価値があると思いました。

Parth picture
2017年06月29日
1

パーティーに遅れて、同じものを探していました。「in」は無効なので、次のように作成しました。

def find_str(full, sub):
    index = 0
    sub_index = 0
    position = -1
    for ch_i,ch_f in enumerate(full) :
        if ch_f.lower() != sub[sub_index].lower():
            position = -1
            sub_index = 0
        if ch_f.lower() == sub[sub_index].lower():
            if sub_index == 0 :
                position = ch_i

            if (len(sub) - 1) <= sub_index :
                break
            else:
                sub_index += 1

    return position

print(find_str("Happy birthday", "py"))
print(find_str("Happy birthday", "rth"))
print(find_str("Happy birthday", "rh"))

を生成します

3
8
-1

大文字と小文字を区別しない検索が不要な場合は、lower()を削除してください。

Anshul picture
2018年05月25日
0

質問に直接答えることはありませんが、最近同様の質問があり、特定の文字列で部分文字列が繰り返される回数を数えるように求められました。 これが私が書いた関数です:

def count_substring(string, sub_string):
    cnt = 0
    len_ss = len(sub_string)
    for i in range(len(string) - len_ss + 1):
        if string[i:i+len_ss] == sub_string:
            cnt += 1
    return cnt

find()関数は、おそらく最初のオカレンスのインデックスのみを返します。 単にカウントする代わりにインデックスを保存すると、サブ文字列が文字列内で繰り返される個別のインデックスのセットを取得できます。

免責事項:私はPythonプログラミングに「非常に」新しいです。

Ali Sajjad picture
2020年05月17日
0

簡単なアプローチは次のとおりです。

my_string = 'abcdefg'
print(text.find('def'))

出力:

3

部分文字列がない場合は、 -1になります。 例えば:

my_string = 'abcdefg'
print(text.find('xyz'))

出力:

-1

部分文字列がない場合は、例外をスローしたい場合があります。

my_string = 'abcdefg'
print(text.index('xyz')) # It returns an index only if it's present

出力:

トレースバック(最後の最後の呼び出し):

ファイル "test.py"、6行目、 print(text.index( 'xyz'))

ValueError:部分文字列が見つかりません