【发布时间】:2011-05-29 11:37:04
【问题描述】:
我有一个类似
的字符串"xdtwkeltjwlkejt7wthwk89lk"
如何获取字符串中第一个数字的索引?
【问题讨论】:
我有一个类似
的字符串"xdtwkeltjwlkejt7wthwk89lk"
如何获取字符串中第一个数字的索引?
【问题讨论】:
instr = 'nkfnkjbvhbef0njhb h2konoon8ll'
numidx = next((i for i, s in enumerate(instr) if s.isdigit()), None)
print(numidx)
输出:
12
numidx 将是instr 中第一次出现的数字的索引。如果instr 中没有数字,则numidx 将是None。
我在这里没有看到这个解决方案,并认为应该是。
【讨论】:
在 Python 3.8+ 中,您可以使用 re.search 查找第一个 \d(用于 digit)字符类,如下所示:
import re
my_string = "xdtwkeltjwlkejt7wthwk89lk"
if first_digit := re.search(r"\d", my_string):
print(first_digit.start())
【讨论】:
import re
result = " Total files:................... 90"
match = re.match(r".*[^\d](\d+)$", result)
if match:
print(match.group(1))
会输出
90
【讨论】:
import re
first_digit = re.search('\d', 'xdtwkeltjwlkejt7wthwk89lk')
if first_digit:
print(first_digit.start())
【讨论】:
使用re.search():
>>> import re
>>> s1 = "thishasadigit4here"
>>> m = re.search(r"\d", s1)
>>> if m:
... print("Digit found at position", m.start())
... else:
... print("No digit in that string")
...
Digit found at position 13
【讨论】:
m.start() 来获取找到的数字(在本例中为 4)?
m.group(0)
isdigit() 方法对我来说始终快了大约 5-6%。
要获取所有索引,请执行以下操作:
idxs = [i for i in range(0, len(string)) if string[i].isdigit()]
然后获取第一个索引:
if len(idxs):
print(idxs[0])
else:
print('No digits exist')
【讨论】:
IndexError 如果您的字符串没有数字,将被提升。
这是一种更好更灵活的方式,这里正则表达式是多余的。
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')]
或者您可以创建一个数字字典及其最后位置
>>> {c: i for i, c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()}
{'9': 22, '8': 21, '7': 15}
【讨论】:
def first_digit_index(iterable):
try:
return next(i for i, d in enumerate(iterable) if d.isdigit())
except StopIteration:
return -1
这不使用正则表达式,一旦找到第一个数字就会停止迭代。
【讨论】:
以为我会把我的方法扔在一堆。我会做任何事情来避免正则表达式。
sequence = 'xdtwkeltjwlkejt7wthwk89lk'
i = [x.isdigit() for x in sequence].index(True)
解释这里发生了什么:
[x.isdigit() for x in sequence] 会将字符串转换为布尔数组,表示每个字符是否为数字[...].index(True) 返回找到 True 的第一个索引值。【讨论】:
ValueError。
这是另一种无正则表达式的方式,更多的是功能风格。这个找到字符串中存在的每个数字第一次出现的位置,然后选择最低的。正则表达式可能会更有效,尤其是对于较长的字符串(这使得至少 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
y = "xdtwkeltjwlkejt7wthwk89lk"
s = re.search("\d",y).start()
【讨论】:
AttributeError 如果您的字符串没有任何数字,则会引发。
正如其他解决方案所说,要找到字符串中第一个数字的索引,我们可以使用正则表达式:
>>> 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
【讨论】:
对于解析器来说似乎是一份不错的工作:
>>> 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
>>> match = re.search("\d", "xdtwkeltjwlkejt7wthwk89lk")
>>> match.start(0)
15
【讨论】:
AttributeError 如果您的字符串没有任何数字,则会引发。