Python: найти индекс первой цифры в строке?
Я подозреваю, что это проблема регулярных выражений - и очень простая, поэтому извиняюсь.
В Python, если у меня есть строка вроде
xdtwkeltjwlkejt7wthwk89lk
как я могу получить индекс первой цифры в строке?
Спасибо!
12 ответов
Использование re.search()
:
>>> import re
>>> s1 = "thishasadigit4here"
>>> m = re.search("\d", s1)
>>> if m:
... print "Digit found at position %d" % m.start()
... else:
... print "No digit in that string"
...
Digit found at position 13
>>>
Вот лучший и более гибкий способ, здесь регулярные выражения излишни.
s='xdtwkeltjwlkejt7wthwk89lk'
for i, c in enumerate(s):
if c.isdigit():
print i
break
выход:
15
Чтобы получить все цифры и их позиции, простое выражение сделает
>>> [(i,c) for i,c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()]
[(15, '7'), (21, '8'), (22, '9')]
В Python 2.7+ вы можете создать разметку цифры и ее положение
>>> {c:i for i,c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()}
{'9': 22, '8': 21, '7': 15}
Думаю, я бы бросил свой метод на кучу. Я сделаю все, чтобы избежать регулярных выражений.
sequence = 'xdtwkeltjwlkejt7wthwk89lk'
i = [x.isdigit() for x in sequence].index(True)
Чтобы объяснить, что здесь происходит:
[x.isdigit() for x in sequence]
собирается преобразовать строку в массив логических значений, представляющих, является ли каждый символ цифрой или нет[...].index(True)
возвращает первое значение индекса,True
находится в.
Похоже, хорошая работа для парсера:
>>> from simpleparse.parser import Parser
>>> s = 'xdtwkeltjwlkejt7wthwk89lk'
>>> grammar = """
... integer := [0-9]+
... <alpha> := -integer+
... all := (integer/alpha)+
... """
>>> parser = Parser(grammar, 'all')
>>> parser.parse(s)
(1, [('integer', 15, 16, None), ('integer', 21, 23, None)], 25)
>>> [ int(s[x[1]:x[2]]) for x in parser.parse(s)[1] ]
[7, 89]
import re
mob = re.search('\d', 'xdtwkeltjwlkejt7wthwk89lk')
if mob:
print mob.start()
Чтобы получить все индексы, выполните:
idxs = [i for i in range(0, len(string)) if string[i].isdigit()]
Затем для получения первого индекса выполните:
idxs[0]
В Python 3.8+ вы можете использовать регулярное выражение на одну строку кода меньше.
import re
my_string = "xdtwkeltjwlkejt7wthwk89lk"
if (first_digit := re.search(r"\d", my_string)) is not None:
print(first_digit.start())
Как говорят другие решения, чтобы найти индекс первой цифры в строке, мы можем использовать регулярные выражения:
>>> s = 'xdtwkeltjwlkejt7wthwk89lk'
>>> match = re.search(r'\d', s)
>>> print match.start() if match else 'No digits found'
15
>>> s[15] # To show correctness
'7'
Несмотря на простоту, совпадение с регулярным выражением будет избыточным для супер-длинных строк. Более эффективный способ - перебрать строку следующим образом:
>>> for i, c in enumerate(s):
... if c.isdigit():
... print i
... break
...
15
В случае, если мы хотим расширить вопрос, чтобы найти первое целое число (не цифра) и что это было:
>>> s = 'xdtwkeltjwlkejt711wthwk89lk'
>>> for i, c in enumerate(s):
... if c.isdigit():
... start = i
... while i < len(s) and s[i].isdigit():
... i += 1
... print 'Integer %d found at position %d' % (int(s[start:i]), start)
... break
...
Integer 711 found at position 15
Вот еще один метод без регулярных выражений, более функциональный. Этот находит позицию первого вхождения каждой цифры, которая существует в строке, затем выбирает самую низкую. Регулярное выражение, вероятно, будет более эффективным, особенно для более длинных строк (это делает по крайней мере 10 полных проходов через строку и до 20).
haystack = "xdtwkeltjwlkejt7wthwk89lk"
digits = "012345689"
found = [haystack.index(dig) for dig in digits if dig in haystack]
firstdig = min(found) if found else None
Я уверен, что есть несколько решений, но с помощью регулярных выражений вы можете сделать это:
>>> import re
>>> match = re.search("\d", "xdtwkeltjwlkejt7wthwk89lk")
>>> match.start(0)
15
Вы можете использовать регулярное выражение
import re
y = "xdtwkeltjwlkejt7wthwk89lk"
s = re.search("\d",y).start()
def first_digit_index(iterable):
try:
return next(i for i, d in enumerate(iterable) if d.isdigit())
except StopIteration:
return -1
Это не использует регулярное выражение и прекратит итерацию, как только будет найдена первая цифра.
У одного из моих коллег был действительно потрясающий ответ на это:
import re
result = " Total files:................... 90"
match = re.match(r".*[^\d](\d+)$", result)
if match:
print match.group(1)
instr = 'nkfnkjbvhbef0njhb h2konoon8ll'
numidx = next((i for i, s in enumerate(instr) if s.isdigit()), None)
print numidx
выход:
12
numidx будет индексом первого появления цифры в instr. Если в instr нет цифр, numidx будет None.
Я не видел здесь этого решения и подумал, что так и должно быть.