it-swarm.com.de

Alle Vorkommen eines Teilstrings in Python suchen

Python hat string.find() und string.rfind(), um den Index einer Teilzeichenfolge in string abzurufen.

Ich frage mich, vielleicht gibt es so etwas wie string.find_all(), das alle fundierten Indizes zurückgeben kann (nicht nur zuerst vom Anfang oder vom Anfang an).

Zum Beispiel:

string = "test test test test"

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

#that's the goal
print string.find_all('test') # [0,5,10,15]
273
nukl

Es gibt keine einfache eingebaute String-Funktion, die das tut, wonach Sie suchen, aber Sie könnten die leistungsfähigeren regulären Ausdrücke verwenden:

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

Wenn Sie nach überlappenden Übereinstimmungen suchen möchten, tun Sie dies mit lookahead :

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

Wenn Sie eine umgekehrte Suchfunktion ohne Überlappungen wünschen, können Sie positiven und negativen Lookahead wie folgt kombinieren:

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

re.finditer gibt einen generator zurück, sodass Sie den [] in () ändern können, um einen Generator anstelle einer Liste zu erhalten, die effizienter ist, wenn Sie die Ergebnisse nur einmal durchlaufen.

421
marcog
>>> help(str.find)
Help on method_descriptor:

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

So können wir es selbst bauen:

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]

Es sind keine temporären Zeichenfolgen oder Regexes erforderlich.

85
Karl Knechtel

Hier ist ein (sehr ineffizienter) Weg, um alle (d. H. Sogar überlappende) Übereinstimmungen zu erhalten:

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

Sie können re.finditer() für nicht überlappende Übereinstimmungen verwenden. 

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

aber wird nicht arbeiten für:

In [1]: aString="ababa"

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

Wieder ein alter Thread, aber hier ist meine Lösung mit einem Generator und einfachem 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)

Beispiel

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

kehrt zurück

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

Kommen Sie, lassen Sie uns zusammen wiederkommen.

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]

Auf diese Weise brauchen Sie keine regulären Ausdrücke.

17
Cody Piersall

Wenn Sie nur nach einem einzelnen Zeichen suchen, würde dies funktionieren:

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

Ebenfalls,

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

Meiner Meinung nach ist keiner der beiden (besonders # 2) furchtbar performant.

8
jstaab

dies ist ein alter Thread, aber ich wurde interessiert und wollte meine Lösung teilen.

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

Es sollte eine Liste der Positionen zurückgegeben werden, an denen der Teilstring gefunden wurde. Bitte kommentieren Sie, wenn Sie einen Fehler oder Verbesserungsbedarf sehen.

8
Thurines

Dieser Thread ist etwas alt, aber das hat für mich funktioniert:

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
Andrew H

Dies macht den Trick für mich mit re.finditer

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()))
3
Bruno Vermeulen

Du kannst es versuchen :

>>> 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
Harsha Biyani

Welche Lösungen auch immer von anderen bereitgestellt werden, hängt vollständig von der verfügbaren Methode find () oder von verfügbaren Methoden ab.

Was ist der grundlegende Algorithmus, um alle Vorkommen eines .__ zu finden. Teilzeichenfolge in einer Zeichenfolge?

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

Sie können die str-Klasse auch an eine neue Klasse erben und diese Funktion verwenden unten.

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

Aufruf der Methode

newstr.find_all ('Findest du diese Antwort hilfreich? dann positiv this!'

2
naveen raja

Sie können leicht verwenden:

string.count('test')!

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

Prost!

0
RaySaraiva

Wenn Sie nach einer großen Anzahl von Schlüsselwörtern in einem Dokument suchen, verwenden Sie 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 wird bei umfangreichen Suchwörtern schneller ausgeführt als regulärer Ausdruck.

0
Uri Goren

Durch Schneiden finden wir alle möglichen Kombinationen und hängen sie in einer Liste an und finden die Häufigkeit, mit der sie auftreten, mit der Funktion 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))
0