একটি স্ট্রিংয়ের সমস্ত উপস্থিতি কীভাবে সন্ধান করবেন?


365

পাইথন হয়েছে string.find()এবং string.rfind()একটি স্ট্রিং একটি সাবস্ট্রিং সূচী জন্য।

আমি ভাবছি এমন কিছু আছে যা কিনা string.find_all()সমস্ত পাওয়া সূচকগুলি (কেবল প্রথম থেকে প্রথমটি নয় বা শেষ থেকে প্রথমটি) ফিরিয়ে আনতে পারে।

উদাহরণ স্বরূপ:

string = "test test test test"

print string.find('test') # 0
print string.rfind('test') # 15

#this is the goal
print string.find_all('test') # [0,5,10,15]

11
কি 'ttt'.find_all('tt')ফিরতে হবে?
সান্তিয়াগো আলেসান্দ্রি

2
এটি '0' ফিরে আসবে। অবশ্যই, নিখুঁত বিশ্বে 'ttt'.rfind_all('tt')
এমনটিও

2
এই সদৃশ মত মনে হয় stackoverflow.com/questions/3873361/...
নিউ এভারেস্ট

উত্তর:


523

কোনও সাধারণ অন্তর্নির্মিত স্ট্রিং ফাংশন নেই যা আপনি যা খুঁজছেন তা করে তবে আপনি আরও শক্তিশালী নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারেন :

import re
[m.start() for m in re.finditer('test', 'test test test test')]
#[0, 5, 10, 15]

আপনি যদি ওভারল্যাপিং ম্যাচগুলি সন্ধান করতে চান তবে লুক হেড তা করবে:

[m.start() for m in re.finditer('(?=tt)', 'ttt')]
#[0, 1]

যদি আপনি ওভারল্যাপ ছাড়াই বিপরীত সন্ধান চান, আপনি ইতিবাচক এবং নেতিবাচক চেহারাটিকে এই জাতীয় মত প্রকাশের সাথে সংযুক্ত করতে পারেন:

search = 'tt'
[m.start() for m in re.finditer('(?=%s)(?!.{1,%d}%s)' % (search, len(search)-1, search), 'ttt')]
#[1]

re.finditerএকটি ফেরৎ জেনারেটর , তাই আপনি পরিবর্তন হতে পারে []করতে উপরে ()একটি তালিকা যা আরও দক্ষ আপনি শুধুমাত্র একবার ফলাফলের মধ্য দিয়ে iterating করছি থাকবে পরিবর্তে একটি জেনারেটরের জন্য।


হাই, এটি সম্পর্কে [m.start() for m in re.finditer('test', 'test test test test')], আমরা কীভাবে সন্ধান করতে পারি testবা করতে পারি text? এটা কি আরও জটিল হয়ে ওঠে?
এক্সপান্ত

7
আপনি সাধারণভাবে নিয়মিত অভিব্যক্তিটি সন্ধান করতে চান: ডকস.পাইথন.আর . / 2 / হাওটো / রিজেক্স.চ.টি.এম.এল । আপনার প্রশ্নের সমাধানটি হ'ল: [মিঃ স্টার্ট () মিটার ইন রি.ফাইন্ডার ('তে [এসএক্সএক্স] টি', 'পাঠ্য পরীক্ষার পাঠ্য পরীক্ষা')]]
ইয়োটাম ভাকনিন

1
এই পদ্ধতিটি ব্যবহারের সময় জটিলতা কী হবে?
প্রাণজাল মিত্তাল

1
@PranjalMittal। উপরের বা নীচে আবদ্ধ? সেরা, সবচেয়ে খারাপ বা গড় কেস?
ম্যাড পদার্থবিদ

@মার্কগ যদি স্ট্রিংগুলিতে বন্ধনী বা অন্যান্য বিশেষ অক্ষর থাকে?
কলাচ

109
>>> help(str.find)
Help on method_descriptor:

find(...)
    S.find(sub [,start [,end]]) -> int

সুতরাং, আমরা নিজেরাই এটি তৈরি করতে পারি:

def find_all(a_str, sub):
    start = 0
    while True:
        start = a_str.find(sub, start)
        if start == -1: return
        yield start
        start += len(sub) # use start += 1 to find overlapping matches

list(find_all('spam spam spam spam', 'spam')) # [0, 5, 10, 15]

কোনও অস্থায়ী স্ট্রিং বা রেজেক্সসের প্রয়োজন নেই।


22
ম্যাচ ওভারল্যাপিং পেতে, এটি প্রতিস্থাপন করতে চলা উচিত start += len(sub)সঙ্গে start += 1
কার্ল নচেটেল

4
আমি বিশ্বাস করি আপনার আগের মন্তব্যটি আপনার উত্তরের একটি পোস্টস্ক্রিপ্ট হওয়া উচিত।
tzot

1
আপনার কোড সাবস্ট্রার সন্ধানের জন্য কাজ করে না: "এ্যাট্যাট" "গ্যাট্যাট্যাটজ্যাক্যাট্যাক্ট"
আশীষ নেগি

2
আমি অতিরিক্ত মন্তব্য করে দেখুন। এটি একটি ওভারল্যাপিং ম্যাচের উদাহরণ।
কার্ল নচেটেল

4
এর আচরণের সাথে মেলে re.findall, আমি len(sub) or 1পরিবর্তে যুক্ত করার পরামর্শ দেব len(sub), অন্যথায় এই জেনারেটরটি খালি সাবস্ট্রিংয়ে কখনও শেষ হবে না।
ডাব্লুজিএইচ

45

সমস্ত (যেমন ওভারল্যাপিং এমনকি) ম্যাচগুলি পাওয়ার একটি (খুব অকার্যকর) উপায় :

>>> string = "test test test test"
>>> [i for i in range(len(string)) if string.startswith('test', i)]
[0, 5, 10, 15]

25

আবার, পুরানো থ্রেড, তবে এখানে জেনারেটর এবং প্লেইন ব্যবহার করে আমার সমাধান দেওয়া হয়েছে str.find

def findall(p, s):
    '''Yields all the positions of
    the pattern p in the string s.'''
    i = s.find(p)
    while i != -1:
        yield i
        i = s.find(p, i+1)

উদাহরণ

x = 'banananassantana'
[(i, x[i:i+2]) for i in findall('na', x)]

আয়

[(2, 'na'), (4, 'na'), (6, 'na'), (14, 'na')]

3
এই সুন্দর দেখাচ্ছে!
fabio.sang

21

আপনি re.finditer()নন-ওভারল্যাপিং মিলগুলির জন্য ব্যবহার করতে পারেন ।

>>> import re
>>> aString = 'this is a string where the substring "is" is repeated several times'
>>> print [(a.start(), a.end()) for a in list(re.finditer('is', aString))]
[(2, 4), (5, 7), (38, 40), (42, 44)]

তবে এর জন্য কাজ করবে না :

In [1]: aString="ababa"

In [2]: print [(a.start(), a.end()) for a in list(re.finditer('aba', aString))]
Output: [(0, 3)]

12
কেন একটি পুনরুক্তি থেকে একটি তালিকা তৈরি করুন, এটি কেবল প্রক্রিয়াটি ধীর করে দেয়।
প্রাদুনসগ

2
aString VS astring;)
NexD।

18

আসুন, আসুন আমরা একসাথে পুনরাবৃত্তি করি।

def locations_of_substring(string, substring):
    """Return a list of locations of a substring."""

    substring_length = len(substring)    
    def recurse(locations_found, start):
        location = string.find(substring, start)
        if location != -1:
            return recurse(locations_found + [location], location+substring_length)
        else:
            return locations_found

    return recurse([], 0)

print(locations_of_substring('this is a test for finding this and this', 'this'))
# prints [0, 27, 36]

এভাবে নিয়মিত প্রকাশের দরকার নেই।


আমি সবেমাত্র অবাক করে দিয়েছি "পাইথনের স্ট্রিংয়ের ভিতরে একটি স্ট্রিংয়ের সন্ধান করার কোনও অভিনব উপায় আছে" ... এবং তারপরে 5 মিনিটের মত গুগল করার পরে আমি আপনার কোডটি পেয়েছি। ভাগ করে নেওয়ার জন্য ধন্যবাদ!!!
গিপারাদা

3
এই কোডটিতে বেশ কয়েকটি সমস্যা রয়েছে। যেহেতু এটি ওপেন-এন্ড ডেটাতে অচিরেই বা পরবর্তী সময়ে কাজ করছে RecursionErrorযদি পর্যাপ্ত পরিমাণে ঘটনা ঘটে থাকে তবে আপনি এতে প্রবেশ করবেন । আর একটি হ'ল দুটি থ্রো-অ্যাওয়ে তালিকাগুলি এটি প্রতিটি পুনরাবৃত্তির উপর কেবল একটি উপাদান সংযোজন করার জন্য তৈরি করে, যা স্ট্রিং সন্ধানের ফাংশনটির জন্য খুব সাবঅপটিমাল, যা সম্ভবত অনেক সময় বলা যেতে পারে। যদিও কখনও কখনও পুনরাবৃত্ত ফাংশন মার্জিত এবং স্পষ্ট মনে হয় তবে তাদের সাবধানতার সাথে নেওয়া উচিত।
ইভান নিকোলাভ

11

আপনি যদি কেবল একটি একক চরিত্রের সন্ধান করেন তবে এটি কাজ করবে:

string = "dooobiedoobiedoobie"
match = 'o'
reduce(lambda count, char: count + 1 if char == match else count, string, 0)
# produces 7

এছাড়াও,

string = "test test test test"
match = "test"
len(string.split(match)) - 1
# produces 4

আমার কুণ্ডলীটি হ'ল এগুলির কোনওটিই (বিশেষত # 2) ভয়াবহ অভিনয় নয়।


gr8 সমাধান .. আমি .. বিভক্ত () ব্যবহার করে মুগ্ধ
শান্তনু পাঠক

9

এটি একটি পুরানো থ্রেড তবে আমি আগ্রহী হয়েছি এবং আমার সমাধানটি ভাগ করে নিতে চাই।

def find_all(a_string, sub):
    result = []
    k = 0
    while k < len(a_string):
        k = a_string.find(sub, k)
        if k == -1:
            return result
        else:
            result.append(k)
            k += 1 #change to k += len(sub) to not search overlapping results
    return result

সাবস্ট্রিংয়ের সন্ধান পাওয়া গেছে এমন পজিশনের একটি তালিকা এটি ফিরে আসবে। আপনি যদি উন্নতির জন্য কোনও ত্রুটি বা ঘর দেখতে পান তবে মন্তব্য করুন।


6

এটি রিফাইন্ডার ব্যবহার করে আমার জন্য কৌশলটি করে

import re

text = 'This is sample text to test if this pythonic '\
       'program can serve as an indexing platform for '\
       'finding words in a paragraph. It can give '\
       'values as to where the word is located with the '\
       'different examples as stated'

#  find all occurances of the word 'as' in the above text

find_the_word = re.finditer('as', text)

for match in find_the_word:
    print('start {}, end {}, search string \'{}\''.
          format(match.start(), match.end(), match.group()))

5

এই থ্রেডটি একটু পুরানো তবে এটি আমার পক্ষে কাজ করেছে:

numberString = "onetwothreefourfivesixseveneightninefiveten"
testString = "five"

marker = 0
while marker < len(numberString):
    try:
        print(numberString.index("five",marker))
        marker = numberString.index("five", marker) + 1
    except ValueError:
        print("String not found")
        marker = len(numberString)

5

আপনি চেষ্টা করতে পারেন :

>>> string = "test test test test"
>>> for index,value in enumerate(string):
    if string[index:index+(len("test"))] == "test":
        print index

0
5
10
15

2

অন্যদের দ্বারা প্রদত্ত সমাধানগুলি যে কোনওভাবেই উপলভ্য পদ্ধতিটি () বা যে কোনও উপলভ্য পদ্ধতির উপর ভিত্তি করে থাকে।

একটি স্ট্রিংয়ের মধ্যে একটি স্ট্রস্ট্রিংয়ের সমস্ত উপস্থিতিগুলি খুঁজে পাওয়ার জন্য মূল মৌলিক অ্যালগরিদম কী?

def find_all(string,substring):
    """
    Function: Returning all the index of substring in a string
    Arguments: String and the search string
    Return:Returning a list
    """
    length = len(substring)
    c=0
    indexes = []
    while c < len(string):
        if string[c:c+length] == substring:
            indexes.append(c)
        c=c+1
    return indexes

আপনি নতুন ক্লাসে স্ট্রেস ক্লাসও উত্তরাধিকারী হতে পারেন এবং নীচে এই ফাংশনটি ব্যবহার করতে পারেন।

class newstr(str):
def find_all(string,substring):
    """
    Function: Returning all the index of substring in a string
    Arguments: String and the search string
    Return:Returning a list
    """
    length = len(substring)
    c=0
    indexes = []
    while c < len(string):
        if string[c:c+length] == substring:
            indexes.append(c)
        c=c+1
    return indexes

পদ্ধতি কলিং

newstr.find_all ('আপনি কি এই উত্তরটি সহায়ক বলে মনে করেন? তারপরে এটিকে উত্সাহিত করুন!', 'এটি')


2

এই ফাংশনটি স্ট্রিংয়ের ভিতরে সমস্ত অবস্থানের দিকে তাকাবে না, এটি গণনা সংস্থানগুলি অপচয় করে না। আমার চেষ্টা:

def findAll(string,word):
    all_positions=[]
    next_pos=-1
    while True:
        next_pos=string.find(word,next_pos+1)
        if(next_pos<0):
            break
        all_positions.append(next_pos)
    return all_positions

এটির জন্য এটি কল করুন:

result=findAll('this word is a big word man how many words are there?','word')

1

কোনও নথিতে বড় পরিমাণে কী শব্দের সন্ধান করার সময়, ফ্ল্যাশটেক্সট ব্যবহার করুন

from flashtext import KeywordProcessor
words = ['test', 'exam', 'quiz']
txt = 'this is a test'
kwp = KeywordProcessor()
kwp.add_keywords_from_list(words)
result = kwp.extract_keywords(txt, span_info=True)

ফ্ল্যাশটেক্সট অনুসন্ধান শব্দের বৃহত তালিকার রেগেক্সের চেয়ে দ্রুত চলে।


0
src = input() # we will find substring in this string
sub = input() # substring

res = []
pos = src.find(sub)
while pos != -1:
    res.append(pos)
    pos = src.find(sub, pos + 1)

1
এই কোডটি ওপির সমস্যার সমাধান করতে পারে তবে আপনার কোডটি কীভাবে ওপি'র সমস্যাটিকে সম্বোধন করে সে সম্পর্কে একটি ব্যাখ্যা অন্তর্ভুক্ত করা ভাল। এইভাবে, ভবিষ্যতের দর্শনার্থীরা আপনার পোস্ট থেকে শিখতে পারবেন এবং এটিকে তাদের নিজস্ব কোডে প্রয়োগ করতে পারেন। এসও কোনও কোডিং পরিষেবা নয়, তবে জ্ঞানের সংস্থান। এছাড়াও, উচ্চ মানের, সম্পূর্ণ উত্তরগুলি আপলোড হওয়ার সম্ভাবনা বেশি। এই বৈশিষ্ট্যগুলি সহ সমস্ত পোস্ট স্বাবলম্বিত হওয়ার প্রয়োজনীয়তার সাথে একটি প্ল্যাটফর্ম হিসাবে এসও এর কিছু শক্তি যা এটি ফোরামে পৃথক করে। আপনি অতিরিক্ত তথ্য যোগ করতে এবং / অথবা উত্স ডকুমেন্টেশন সহ আপনার ব্যাখ্যা পরিপূরক করতে সম্পাদনা করতে পারেন
শেরিলহোম্যান

0

এটি হ্যাকারঙ্ক থেকে অনুরূপ প্রশ্নের সমাধান। আমি আশা করি এটি আপনাকে সহায়তা করতে পারে।

import re
a = input()
b = input()
if b not in a:
    print((-1,-1))
else:
    #create two list as
    start_indc = [m.start() for m in re.finditer('(?=' + b + ')', a)]
    for i in range(len(start_indc)):
        print((start_indc[i], start_indc[i]+len(b)-1))

আউটপুট:

aaadaa
aa
(0, 1)
(1, 2)
(4, 5)

-1

টুকরো টুকরো করে আমরা সম্ভব সমস্ত সংমিশ্রণগুলি খুঁজে পেতে পারি এবং একটি তালিকায় এগুলি সংযোজন করি এবং countফাংশনটি ব্যবহার করে এটি কতবার সংঘটিত হয় তা সন্ধান করি

s=input()
n=len(s)
l=[]
f=input()
print(s[0])
for i in range(0,n):
    for j in range(1,n+1):
        l.append(s[i:j])
if f in l:
    print(l.count(f))

কখন s="test test test test"এবং f="test"আপনার কোড প্রিন্ট করে 4তবে ওপি প্রত্যাশিত[0,5,10,15]
বার্বসান

একটি একক শব্দের জন্য লিখেছেন কোডটি আপডেট করবে
বন্টা শ্রীভিধ্যা

-2

নীচের কোড দেখুন

#!/usr/bin/env python
# coding:utf-8
'''黄哥Python'''


def get_substring_indices(text, s):
    result = [i for i in range(len(text)) if text.startswith(s, i)]
    return result


if __name__ == '__main__':
    text = "How much wood would a wood chuck chuck if a wood chuck could chuck wood?"
    s = 'wood'
    print get_substring_indices(text, s)

-2

পাইথোনিক উপায়টি হ'ল:

mystring = 'Hello World, this should work!'
find_all = lambda c,s: [x for x in range(c.find(s), len(c)) if c[x] == s]

# s represents the search string
# c represents the character string

find_all(mystring,'o')    # will return all positions of 'o'

[4, 7, 20, 26] 
>>> 

3
1) 7 বছর আগে উত্তর দেওয়া একটি প্রশ্নের এটি কীভাবে সহায়তা করে? 2) এইভাবে ব্যবহার করা lambdaপাইথোনিক নয় এবং পিইপি 8 এর বিপরীতে যায় । 3) এটি
ওপিএস

পাইথোনিকের অর্থ এই নয় যে "পাইথনের যতগুলি বৈশিষ্ট্য আপনি এটি ভাবতে পারেন সেভাবে ব্যবহার করুন"
ক্লুত

-2

আপনি সহজেই ব্যবহার করতে পারেন:

string.count('test')!

https://www.programiz.com/python-programming/methods/string/count

চিয়ার্স!



8
স্ট্রিং কাউন্ট () পদ্ধতিটি প্রদত্ত স্ট্রিংয়ে একটি স্ট্রিংয়ের সংখ্যার সংখ্যা প্রদান করে। তাদের অবস্থান নয়।
অ্যাস্ট্রিড

5
এটি সমস্ত ক্ষেত্রে সন্তুষ্ট হয় না, s = 'কলা', সাব = 'আনা'। সাব এই পরিস্থিতিতে দু'বার দেখা দেয় কিন্তু এস.এসব ('আনা') করলে 1 ফিরে আসবে
জো ড্যানিয়েল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.