Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.
Позиция вашего DOM-зависимого скрипта может оказать глубокое влияние на его поведение. Браузеры анализируют HTML-документы сверху донизу. Элементы добавляются в DOM, и сценарии выполняются (как правило), когда они встречаются. Это означает, что порядок имеет значение. Как правило, скрипты не могут найти элементы, которые появляются позже в разметке, потому что эти элементы еще не добавлены в DOM.
Рассмотрим следующую разметку; сценарий # 1 не находит Итак, что вы должны делать? У вас есть несколько вариантов: Переместите свой скрипт дальше по странице, перед закрывающим тегом тела. Организованный таким образом остальная часть документа анализируется до того, как будет выполнен ваш скрипт: Примечание: размещение скриптов внизу как правило, считается лучшей практикой . Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя Примечание. Вы можете просто привязать к Делегированные события имеют преимущество в том, что они могут обрабатывать события из элементов-потомков, которые будут добавлены в документ позже. Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код. jQuery Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к Используйте атрибут [ Для справки, вот код из этого внешнего скрипта : Примечание: атрибут
Вариант 1: Переместите свой скрипт
Вариант 2: jQuery's
ready()
ready()
:
DOMContentLoaded
или window.onload
, но у каждого есть свои оговорки. jQuery ready()
предоставляет гибридное решение. Вариант 3: Делегирование событий
on()
выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:
document
(для демонстрационных целей), вы должны выбрать ближайшего надежного предка. Вариант 4: Атрибут
defer
defer
в .
defer
, логический атрибут] установлен для указания на браузера, который должен выполняться после того, как документ был проанализирован.
document.getElementById("test").addEventListener("click", function(e){
console.log("clicked: %o", this);
});
defer
, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer
может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src
. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10
Нет простой встроенной строковой функции, которая делает то, что вы ищете, но вы можете использовать более мощные регулярные выражения :
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
возвращает генератор , поэтому вы можете изменить []
выше, на ()
, чтобы получить генератор вместо списка, который будет более эффективен, если вы только итерации через результаты один раз.
Опять же, старый поток, но вот мое решение с использованием генератора и простой 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')]
Вы можете использовать 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)]
Это делает трюк для меня, используя 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()))
Приходите, давайте реорганизовать вместе.
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]
Таким образом, нет необходимости в регулярных выражениях.
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
Если вы ищете только один символ, это будет работать:
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) ужасно совершенен.
Независимо от решений, предоставляемых другими, полностью основаны на доступном методе find () или любых доступных методах.
Каков основной базовый алгоритм для поиска всех вхождений подстроки в string?
blockquote>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 новому классу и можете использовать эту функцию ниже.
blockquote>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 («Вы находите, что этот ответ полезен, а затем повышайте это!», «это»)
blockquote>
Питонический путь:
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]
>>>
lambda
, этот путь не является Pythonic и идет против PEP8 . 3) Это не дает правильного выхода для ситуации OPs
– Wondercricket
10 April 2018 в 19:47
>>> 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]
Не требуется временных строк или регулярных выражений.
start += len(sub)
на start += 1
.
– Karl Knechtel
12 January 2011 в 04:13
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]
Это старый поток, но я заинтересовался и хотел поделиться своим решением.
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
Он должен вернуть список позиций, где была найдена подстрока. Прокомментируйте, если вы видите ошибку или комнату для улучшения.
Этот поток немного стар, но это сработало для меня:
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)
, посмотрите ниже код
#!/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)
[m.start() for m in re.finditer('test', 'test test test test')]
, как мы можем искатьtest
илиtext
? Становится ли это намного сложнее? – xpanta 1 March 2013 в 12:48