如何使用Python判断字符串是否以数字开头?

140

我有一个以数字(0-9)开头的字符串。我知道我可以使用startswith()函数连续进行10个测试,但可能存在更简洁的解决方案。

因此,不必写出以下代码:

if (string.startswith('0') || string.startswith('2') ||
    string.startswith('3') || string.startswith('4') ||
    string.startswith('5') || string.startswith('6') ||
    string.startswith('7') || string.startswith('8') ||
    string.startswith('9')):
    #do something

有更聪明/更有效的方法吗?


1
如果有人问:“这个是否太过重复了?”,那么在高级语言中,答案很可能是:“是的,确实如此”。偷懒! - user166390
58
你漏掉了 string.startswith('1') - MAK
2
@Illusionist 根据你的问题,你想检测以一个数字开头的字符串。如果是这样,以下答案中唯一正确的答案不是使用 s[0]s[:1] 的答案,而是 John Machin 的解决方案:if s.startswith(tuple('0123456789'))。此外,当发生 s 是元组或列表等序列时,该解决方案会引发错误,这些情况产生与字符串相同的结果。- 另一种解决方案是正则表达式,其模式为 **'\d(?=\D)'**,但在这里使用正则表达式是多余的。 - eyquem
4
有点吹毛求疵,string是标准库中的一个模块,可能不应该用作变量名。http://docs.python.org/2/library/string.html - gak
12个回答

243

Python的 string 库有一个 isdigit() 方法:

string[0].isdigit()

7
Python2的string模块没有方法,isdigitstrunicode对象的一个方法。 - John Machin
3
由于以上原因以及如果s == ""时会崩溃,@plaes被评为-1。 - John Machin
7
看看我的答案,它不会因为空字符串而出错:string[:1].isdigit() - PascalVKooten

34
>>> string = '1abc'
>>> string[0].isdigit()
True

1
我不是 Python 方面的专家,所以或许你能帮我解决这个问题:当 string 为空时(即没有 string[0]),这个函数会出错吗? - corsiKa
当然可以。您可以使用(string或'x')[0] .isdigit()来修复''或None的问题。 - jcomeau_ictx
34
你可以尝试使用 string[:1].isdigit(),这将可以很好地处理空字符串。 - Simon Callan
那为什么不编辑答案以反映@SimonCallan的建议呢? - MERose
2
因为那不是我的答案;在程序员希望在空字符串上抛出异常的情况下,我的答案仍然更好。 - jcomeau_ictx
1
@jcomeau_ictx 完全正确。永远不要防御性地编程。如果字符串意外为空,那么应该出现错误,而且不应该自动处理。有些思想流派认为,你应该优雅地处理和捕获那些不是关键的异常作为警告,并保持程序运行。对于大多数用例,我不持有这种观点。在你编写的函数和代码中的特定性有助于减轻你需要更经常地进行防御性编码的边缘情况。 - james-see

28

令人惊讶的是,经过这么长时间仍然找不到最好的答案。

其他答案的缺点是使用[0]选择第一个字符,但如注释所述,这会在空字符串上出现问题。

以下方法解决了这个问题,并且,在我看来,它提供了我们拥有的选项中最漂亮、最易读的语法。 它也不需要导入/麻烦正则表达式):

>>> string = '1abc'
>>> string[:1].isdigit()
True

>>> string = ''
>>> string[:1].isdigit()
False

12

有时候,你可以使用正则表达式

>>> import re
>>> re.search('^\s*[0-9]',"0abc")
<_sre.SRE_Match object at 0xb7722fa8>

过度杀伤!为什么要使用re,当你可以在内置函数中完成它。 - Jakob Bowyer
1
@JakobBowyer 至少知道这点很好!即使在这种情况下,如果一些内置函数可以完成相同的工作,正则表达式也是过度使用。 - jeromej

9
你的代码无法运行;你需要使用or代替||
尝试:
'0' <= strg[:1] <= '9'

或者

strg[:1] in '0123456789'

或者,如果您真的很喜欢startswith()函数,
strg.startswith(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))

如果只有使用 startswith(a tuple) 的解决方案,我会给你点赞的。但是使用 strg[:1] 的解决方案有两个不便之处:如果 s 可能是字符串列表,则它们不会引发错误,并且如果字符串以多个数字开头,则它们会产生 True - eyquem
@eyquem 如果字符串以多个数字开头,则它们会生成True 那又怎样?其他答案没有检查这一点,因为它不是必须要检查其他字符是否为数字的要求。 - Rob Grant
我对startswith非常着迷,并在我的代码中实现了它。谢谢。 - james-see
另一种startswith的可能性... startswith(tuple(str(i) for i in range(10))) - Jérôme
.isdigit() 是首选。 - PascalVKooten

4
这段代码:
for s in ("fukushima", "123 is a number", ""):
    print s.ljust(20),  s[0].isdigit() if s else False

打印输出如下内容:
fukushima            False
123 is a number      True
                     False

4
很丑。使用 s[:1].isdigit() 或者 s and s[0].isdigit() - John Machin
1
@John Machin,您所说的“丑陋”是什么意思?不易读吗?我认为您在上面提出的建议也不太容易读懂。在我看来,“s and s[0].isdigit()”甚至更难以理解。就我个人而言,我喜欢使用“**... if ... else ...**”结构。考虑到您的评论,我只会对它进行改进,如下所示:“s[0].isdigit() if s!="" else False”。 - eyquem

3
使用内置的string模块
>>> import string
>>> '30 or older'.startswith(tuple(string.digits))

接受的回答对于单个字符串很有效。我需要一种适用于pandas.Series.str.contains的方法。可以说比使用正则表达式更易读,并且是使用一个似乎不太知名的模块的好方法。

2

你也可以使用 try...except


try:
    int(string[0])
    # do your stuff
except:
    pass # or do your stuff

1

这是我的“答案”(在这里尝试独特,实际上我并不推荐这两种方法用于这个特定的情况 :-)

使用ord()特殊的a <= b <= c形式:

//starts_with_digit = ord('0') <= ord(mystring[0]) <= ord('9')
//I was thinking too much in C. Strings are perfectly comparable.
starts_with_digit = '0' <= mystring[0] <= '9'

这个 a <= b <= c,就像 a < b < c,是 Python 中的一种特殊结构,非常巧妙:比较 1 < 2 < 3(真)和 1 < 3 < 2(假),以及 (1 < 3) < 2(真)。这在大多数其他语言中都不是这样工作的。

使用 正则表达式

import re
//starts_with_digit = re.match(r"^\d", mystring) is not None
//re.match is already anchored
starts_with_digit = re.match(r"\d", mystring) is not None

1
(1)去掉 ord()。 (2)在正则表达式中去掉 ^ - John Machin

0
你可以使用正则表达式
你可以使用以下方法检测数字:
if(re.search([0-9], yourstring[:1])):
#do something

[0-9]匹配任何数字,而yourstring[:1]匹配您字符串的第一个字符


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接