Hoe vind je alle exemplaren van een subtekenreeks?

Python heeft string.find()en string.rfind()om de index van een substring in een string te krijgen.

Ik vraag me af of er zoiets is als string.find_all()dat alle gevonden indexen kan retourneren (niet alleen de eerste vanaf het begin of de eerste vanaf het einde).

Bijvoorbeeld:

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]

Antwoord 1, autoriteit 100%

Er is geen eenvoudige ingebouwde tekenreeksfunctie die doet wat u zoekt, maar u kunt de krachtigere reguliere uitdrukkingen:

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

Als u overlappende overeenkomsten wilt vinden, doet lookaheaddat:

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

Als u een omgekeerde zoekactie wilt zonder overlappingen, kunt u positieve en negatieve vooruitkijken combineren in een uitdrukking als deze:

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

re.finditergeeft een generator, dus je zou de []hierboven kunnen veranderen in ()om een ​​generator te krijgen in plaats van een lijst die efficiënter is als je de resultaten maar één keer doorloopt.


Antwoord 2, autoriteit 22%

>>> help(str.find)
Help on method_descriptor:
find(...)
    S.find(sub [,start [,end]]) -> int

Zo kunnen we het zelf bouwen:

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]

Geen tijdelijke strings of regexes vereist.


Antwoord 3, autoriteit 10%

Hier is een (zeer inefficiënte) manier om alle(d.w.z. zelfs overlappende) overeenkomsten te krijgen:

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

Antwoord 4, autoriteit 7%

Nogmaals, oude thread, maar hier is mijn oplossing met behulp van een generatoren gewone 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)

Voorbeeld

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

retouren

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

Antwoord 5, autoriteit 4%

Je kunt re.finditer()gebruiken voor niet-overlappende overeenkomsten.

>>> 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)]

maar zal nietwerken voor:

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

Antwoord 6, autoriteit 3%

Kom, laten we samen terugkomen.

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]

Op deze manier zijn reguliere expressies niet nodig.


Antwoord 7, autoriteit 2%

Als u slechts één teken zoekt, zou dit werken:

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

Ook

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

Mijn vermoeden is dat geen van beide (vooral #2) erg goed presteert.


Antwoord 8, autoriteit 2%

dit is een oude thread, maar ik raakte geïnteresseerd en wilde mijn oplossing delen.

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

Het zou een lijst met posities moeten retourneren waar de substring is gevonden.
Geef een reactie als je een fout of ruimte voor verbetering ziet.


Antwoord 9

Dit werkt voor mij als ik re.finditer gebruik

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()))

Antwoord 10

Deze thread is een beetje oud, maar dit werkte voor mij:

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)

Antwoord 11

Je kunt proberen:

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

Antwoord 12

Wat de oplossingen van anderen ook zijn, ze zijn volledig gebaseerd op de beschikbare methode find() of andere beschikbare methoden.

Wat is het basisalgoritme om alle voorkomens van a . te vinden?
subtekenreeks in een tekenreeks?

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

Je kunt ook de klasse str overnemen van een nieuwe klasse en deze functie gebruiken
hieronder.

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

De methode aanroepen

newstr.find_all(‘Vind je dit antwoord nuttig? Dan upvote
dit!’,’dit’)


Antwoord 13

Als je een groot aantal trefwoorden in een document zoekt, gebruik dan flashtext

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)

Flashtext werkt sneller dan regex op een grote lijst met zoekwoorden.


Antwoord 14

Deze functie kijkt niet naar alle posities binnen de string, het verspilt geen rekenbronnen. Mijn poging:

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

om het te gebruiken, noem het zo:

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

Antwoord 15

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)

Antwoord 16

Dit is een oplossing voor een soortgelijke vraag van hackerrank. Ik hoop dat dit je kan helpen.

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))

Uitvoer:

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

Antwoord 17

def find_index(string, let):
    enumerated = [place  for place, letter in enumerate(string) if letter == let]
    return enumerated

bijvoorbeeld:

find_index("hey doode find d", "d") 

retourneert:

[4, 7, 13, 15]

Antwoord 18

als je alleen numpy wilt gebruiken, is hier een oplossing

import numpy as np
S= "test test test test"
S2 = 'test'
inds = np.cumsum([len(k)+len(S2) for k in S.split(S2)[:-1]])- len(S2)
print(inds)

Antwoord 19

Niet precies wat OP vroeg, maar je zou ook de split-functie kunnen gebruiken om een ​​lijst te krijgen van waar alle substrings nietvoorkomen. OP heeft het einddoel van de code niet gespecificeerd, maar als het je doel is om de substrings toch te verwijderen, kan dit een eenvoudige one-liner zijn. Er zijn waarschijnlijk efficiëntere manieren om dit te doen met grotere snaren; reguliere expressies zouden in dat geval de voorkeur hebben

# Extract all non-substrings
s = "an-example-string"
s_no_dash = s.split('-')
# >>> s_no_dash
# ['an', 'example', 'string']
# Or extract and join them into a sentence
s_no_dash2 = ' '.join(s.split('-'))
# >>> s_no_dash2
# 'an example string'

Heeft een korte samenvatting gegeven van andere antwoorden, dus excuses als dit er al staat.


Antwoord 20

def count_substring(string, sub_string):
    c=0
    for i in range(0,len(string)-2):
        if string[i:i+len(sub_string)] == sub_string:
            c+=1
    return c
if __name__ == '__main__':
    string = input().strip()
    sub_string = input().strip()
    count = count_substring(string, sub_string)
    print(count)

Antwoord 21

De pythonische manier zou zijn:

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] 
>>> 

Antwoord 22

Door te slicen vinden we alle mogelijke combinaties en voegen ze toe aan een lijst en vinden het aantal keren dat het voorkomt met de functie 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))

Antwoord 23

Ik liep tegen hetzelfde probleem aan en deed dit:

hw = 'Hello oh World!'
list_hw = list(hw)
o_in_hw = []
while True:
    o = hw.find('o')
    if o != -1:
        o_in_hw.append(o)
        list_hw[o] = ' '
        hw = ''.join(list_hw)
    else:
        print(o_in_hw)
        break

Ik ben vrij nieuw in coderen, dus je kunt het waarschijnlijk vereenvoudigen (en indien gepland om het continu te gebruiken natuurlijk, maak er een functie van).

Al met al werkt het zoals bedoeld voor wat ik aan het doen was.

Bewerken: houd er rekening mee dat dit alleen voor enkele tekens is, en het zal uw variabele veranderen, dus u moet een kopie van de tekenreeks in een nieuwe variabele maken om deze op te slaan, ik heb het niet in de code geplaatst omdat het gemakkelijk en het is alleen om te laten zien hoe ik het heb laten werken.


Antwoord 24

kijk alstublieft naar onderstaande code

#!/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)

Antwoord 25

U kunt eenvoudig het volgende gebruiken:

string.count('test')!

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

Proost!

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes