Python Найти слово в тексте [дубликат]

Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.

Позиция вашего DOM-зависимого скрипта может оказать глубокое влияние на его поведение. Браузеры анализируют HTML-документы сверху донизу. Элементы добавляются в DOM, и сценарии выполняются (как правило), когда они встречаются. Это означает, что порядок имеет значение. Как правило, скрипты не могут найти элементы, которые появляются позже в разметке, потому что эти элементы еще не добавлены в DOM.

Рассмотрим следующую разметку; сценарий # 1 не находит

, а сценарий # 2 преуспевает:


test div

Итак, что вы должны делать? У вас есть несколько вариантов:


Вариант 1: Переместите свой скрипт

Переместите свой скрипт дальше по странице, перед закрывающим тегом тела. Организованный таким образом остальная часть документа анализируется до того, как будет выполнен ваш скрипт:


  
  

Примечание: размещение скриптов внизу как правило, считается лучшей практикой .


Вариант 2: jQuery's ready()

Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя

ready() :



Примечание. Вы можете просто привязать к DOMContentLoaded или window.onload, но у каждого есть свои оговорки. jQuery ready() предоставляет гибридное решение.


Вариант 3: Делегирование событий

Делегированные события имеют преимущество в том, что они могут обрабатывать события из элементов-потомков, которые будут добавлены в документ позже.

Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код.

jQuery on() выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:



Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к document (для демонстрационных целей), вы должны выбрать ближайшего надежного предка.


Вариант 4: Атрибут defer

Используйте атрибут defer в

Для справки, вот код из этого внешнего скрипта :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

Примечание: атрибут defer, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10

245
задан nihiser 11 July 2013 в 19:34
поделиться

15 ответов

Нет простой встроенной строковой функции, которая делает то, что вы ищете, но вы можете использовать более мощные регулярные выражения :

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

Если вы хотите найти совпадающие совпадения, lookahead будет делать это:

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

Если вы хотите иметь обратную find-all без перекрытий, вы можете комбинировать положительный и отрицательный lookahead в выражении типа это:

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

re.finditer возвращает генератор , поэтому вы можете изменить [] выше, на (), чтобы получить генератор вместо списка, который будет более эффективен, если вы только итерации через результаты один раз.

376
ответ дан David Leon 17 August 2018 в 22:44
поделиться
  • 1
    привет, относительно этого [m.start() for m in re.finditer('test', 'test test test test')], как мы можем искать test или text? Становится ли это намного сложнее? – xpanta 1 March 2013 в 12:48
  • 2
    Вы хотите посмотреть в регулярное выражение в целом: docs.python.org/2/howto/regex.html . Решение вашего вопроса будет: [m.start () для m в re.finditer ('te [sx] t', 'text test text test')] – Yotam Vaknin 6 May 2014 в 11:21
  • 3
    Какова будет временная сложность использования этого метода? – Pranjal Mittal 13 July 2017 в 23:50
  • 4
    Regex is evil, никогда не использовать его – Alek Depler 25 January 2018 в 15:37
  • 5
    @Alex Depler: Regex is evil why ? – some-non-descript-user 6 June 2018 в 08:04

Опять же, старый поток, но вот мое решение с использованием генератора и простой 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')]
13
ответ дан AkiRoss 17 August 2018 в 22:44
поделиться

Вы можете использовать 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)]
17
ответ дан AnukuL 17 August 2018 в 22:44
поделиться
  • 1
    Зачем составлять список из итератора, это просто замедляет процесс. – pradyunsg 13 May 2013 в 11:57
  • 2
    Строка VS string;) – NexD. 15 November 2016 в 15:51
  • 3
    это не будет работать под подстроками типа aa или bb – Coder anonymous 22 May 2017 в 11:33

Это делает трюк для меня, используя 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()))
1
ответ дан Bruno Vermeulen 17 August 2018 в 22:44
поделиться

Приходите, давайте реорганизовать вместе.

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]

Таким образом, нет необходимости в регулярных выражениях.

15
ответ дан Cody Piersall 17 August 2018 в 22:44
поделиться
  • 1
    Я только начал удивляться, «есть ли фантастический способ найти подстроку внутри строки в python» ... а затем через 5 минут поиска в Google я нашел ваш код. Спасибо, что поделился!!! – Geparada 5 August 2014 в 19:22
  • 2
    Этот код имеет несколько проблем. Так как он работает с открытыми данными рано или поздно, вы столкнетесь с RecursionError, если их будет достаточно. Еще один - два отбрасываемых списка, которые он создает на каждой итерации только для добавления одного элемента, который очень субоптимален для функции поиска строк, которую можно было бы назвать много раз. Хотя иногда рекурсивные функции кажутся элегантными и понятными, их следует принимать с осторожностью. – Ivan Nikolaev 15 November 2016 в 09:54

Вы можете попробовать:

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

0
5
10
15
1
ответ дан Harsha B 17 August 2018 в 22:44
поделиться

Если вы ищете только один символ, это будет работать:

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) ужасно совершенен.

7
ответ дан jstaab 17 August 2018 в 22:44
поделиться

Независимо от решений, предоставляемых другими, полностью основаны на доступном методе find () или любых доступных методах.

Каков основной базовый алгоритм для поиска всех вхождений подстроки в string?

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

Вы также можете наследовать класс str новому классу и можете использовать эту функцию ниже.

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 («Вы находите, что этот ответ полезен, а затем повышайте это!», «это»)

1
ответ дан naveen raja 17 August 2018 в 22:44
поделиться

Питонический путь:

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] 
>>> 
-1
ответ дан perror 17 August 2018 в 22:44
поделиться
>>> 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]

Не требуется временных строк или регулярных выражений.

77
ответ дан Pratik Deoghare 17 August 2018 в 22:44
поделиться
  • 1
    Чтобы получить совпадающие совпадения, достаточно заменить start += len(sub) на start += 1. – Karl Knechtel 12 January 2011 в 04:13
  • 2
    Я считаю, что ваш предыдущий комментарий должен быть постскриптумом в вашем ответе. – tzot 6 February 2011 в 20:27
  • 3
    Ваш код не работает для поиска substr: & quot; ATAT & quot; в "GATATATGCATATACTT" – Ashish Negi 5 October 2013 в 08:08
  • 4
    См. Комментарий, который я сделал дополнительно. Это пример совпадающего совпадения. – Karl Knechtel 14 October 2013 в 01:13
  • 5
    Чтобы соответствовать поведению re.findall, я бы рекомендовал добавить len(sub) or 1 вместо len(sub), иначе этот генератор никогда не завершится на пустой подстроке. – WGH 27 November 2015 в 01:15

Вот (очень неэффективный) способ получить все (т. е. даже совпадающие):

>>> string = "test test test test"
>>> [i for i in range(len(string)) if string.startswith('test', i)]
[0, 5, 10, 15]
35
ответ дан thkala 17 August 2018 в 22:44
поделиться
  • 1
    @BlaXpirit: true, выход range() основан на нуле. Благодаря... – thkala 21 April 2013 в 09:37

Это старый поток, но я заинтересовался и хотел поделиться своим решением.

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

Он должен вернуть список позиций, где была найдена подстрока. Прокомментируйте, если вы видите ошибку или комнату для улучшения.

7
ответ дан Thurines 17 August 2018 в 22:44
поделиться

Этот поток немного стар, но это сработало для меня:

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)
3
ответ дан Winger Sendon 17 August 2018 в 22:44
поделиться

, посмотрите ниже код

#!/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
ответ дан 黄哥Python培训 17 August 2018 в 22:44
поделиться
0
ответ дан Uri Goren 29 October 2018 в 20:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: