检查字符串是否包含数字


193

我发现的大多数问题都偏向于他们正在寻找数字中的字母的事实,而我正在寻找我想成为无数字符串的数字。我需要输入一个字符串,并检查它是否包含任何数字以及是否确实拒绝它。

isdigit()True当所有字符均为数字时,该函数才返回。我只想看看用户是否输入了一个数字,如一个句子之类的"I own 1 dog"

有任何想法吗?

Answers:


290

您可以像这样使用any函数和str.isdigit函数

>>> def hasNumbers(inputString):
...     return any(char.isdigit() for char in inputString)
... 
>>> hasNumbers("I own 1 dog")
True
>>> hasNumbers("I own no dog")
False

另外,您可以使用正则表达式,如下所示

>>> import re
>>> def hasNumbers(inputString):
...     return bool(re.search(r'\d', inputString))
... 
>>> hasNumbers("I own 1 dog")
True
>>> hasNumbers("I own no dog")
False

那负数呢?

@Ray然后可以这样扩展RegExr'-?\d+'
thefourtheye

15
反正原始正则表达式是否不会检测到负数?
confused00

1
@ confused00不,\d将范围仅匹配一个单一的数字09
thefourtheye

9
@thefourtheye:-1仍然是一个数字。它是一个破折号,后跟数字“ 1”
user3183018 '17

49

您可以使用组合anystr.isdigit

def num_there(s):
    return any(i.isdigit() for i in s)

True如果字符串中存在数字,则该函数将返回,否则返回False

演示:

>>> king = 'I shall have 3 cakes'
>>> num_there(king)
True
>>> servant = 'I do not have any cakes'
>>> num_there(servant)
False

无需创建临时列表,您可以使用生成器表达式来代替,而只需删除那些方括号即可。
Matteo Italia

是的,刚刚意识到可以any接受生成器表达式。
aikid


28

https://docs.python.org/2/library/re.html

您最好使用正则表达式。它要快得多。

import re

def f1(string):
    return any(i.isdigit() for i in string)


def f2(string):
    return re.search('\d', string)


# if you compile the regex string first, it's even faster
RE_D = re.compile('\d')
def f3(string):
    return RE_D.search(string)

# Output from iPython
# In [18]: %timeit  f1('assdfgag123')
# 1000000 loops, best of 3: 1.18 µs per loop

# In [19]: %timeit  f2('assdfgag123')
# 1000000 loops, best of 3: 923 ns per loop

# In [20]: %timeit  f3('assdfgag123')
# 1000000 loops, best of 3: 384 ns per loop

f3没有返回任何内容
pyd

这意味着没有匹配,它将返回None
zyxue

RE_D = re.compile('\ d')def has_digits(string):res = RE_D.search(string)返回res不是None
Raul

8

您可以在字符串中的每个字符上应用isdigit()函数。或者您可以使用正则表达式。

我也找到了如何在Python的字符串中找到一个数字?以非常适合的方式返回数字。以下解决方案来自该问题的答案。

number = re.search(r'\d+', yourString).group()

或者:

number = filter(str.isdigit, yourString)

有关更多信息,请查看正则表达式文档:http : //docs.python.org/2/library/re.html

编辑:这将返回实际数字,而不是布尔值,因此以上答案对于您的情况更为正确

第一种方法将返回第一个数字和后续的连续数字。因此1.56将被返回为1。10,000将被返回为10。0207-100-1000将被返回为0207。

第二种方法不起作用。

要提取所有数字,点和逗号,并且不丢失非连续数字,请使用:

re.sub('[^\d.,]' , '', yourString)

3

您可以使用NLTK方法。

这将在文本中找到“ 1”和“ One”:

import nltk 

def existence_of_numeric_data(text):
    text=nltk.word_tokenize(text)
    pos = nltk.pos_tag(text)
    count = 0
    for i in range(len(pos)):
        word , pos_tag = pos[i]
        if pos_tag == 'CD':
            return True
    return False

existence_of_numeric_data('We are going out. Just five you and me.')


2

您可以使用带有计数的范围来检查数字在字符串中出现的次数,方法是对照范围进行检查:

def count_digit(a):
    sum = 0
    for i in range(10):
        sum += a.count(str(i))
    return sum

ans = count_digit("apple3rh5")
print(ans)

#This print 2

2

我很惊讶没有人提到anyand的组合map

def contains_digit(s):
    isdigit = str.isdigit
    return any(map(isdigit,s))

在python 3中,它可能最快(因为正则表达式除外)是因为它不包含任何循环(并且对该函数进行别名避免了在中查找它str)。

不要在python 2中使用它作为map返回a list,这会中断any短路


2

这个如何?

import string

def containsNumber(line):
    res = False
    try:
        for val in line.split():
            if (float(val.strip(string.punctuation))):
                res = True
                break
    except ValueError:
        pass
    return res

containsNumber('234.12 a22') # returns True
containsNumber('234.12L a22') # returns False
containsNumber('234.12, a22') # returns True

1
请不要只是将您的源代码放在这里。保持友善,并尝试对您的答案给出一个很好的描述,以便其他人会喜欢并赞成。请参阅:我如何写一个好的答案?
sɐunıɔןɐqɐp

2

我将使@zyxue答案更加明确:

RE_D = re.compile('\d')

def has_digits(string):
    res = RE_D.search(string)
    return res is not None

has_digits('asdf1')
Out: True

has_digits('asdf')
Out: False

这是@zyxue在答案中提出的解决方案中最快的基准解决方案。


1

更简单的解决方法是

s = '1dfss3sw235fsf7s'
count = 0
temp = list(s)
for item in temp:
    if(item.isdigit()):
        count = count + 1
    else:
        pass
print count

1
欢迎使用Stack Overflow!请不要只是将您的源代码放在这里。保持友善,并尝试对您的答案给出一个很好的描述,以便其他人会喜欢并赞成。请参阅:我如何写一个好的答案?
sɐunıɔןɐqɐp

1
import string
import random
n = 10

p = ''

while (string.ascii_uppercase not in p) and (string.ascii_lowercase not in p) and (string.digits not in p):
    for _ in range(n):
        state = random.randint(0, 2)
        if state == 0:
            p = p + chr(random.randint(97, 122))
        elif state == 1:
            p = p + chr(random.randint(65, 90))
        else:
            p = p + str(random.randint(0, 9))
    break
print(p)

此代码生成大小为n的序列,该序列至少包含一个大写字母,一个小写字母和一个数字。通过使用while循环,我们保证了该事件。


请加解释你的答案
Mastisa

1

any并且ord可以被组合以达到目的如下所示。

>>> def hasDigits(s):
...     return any( 48 <= ord(char) <= 57 for char in s)
...
>>> hasDigits('as1')
True
>>> hasDigits('as')
False
>>> hasDigits('as9')
True
>>> hasDigits('as_')
False
>>> hasDigits('1as')
True
>>>

关于此实现的几点。

  1. any 更好,因为它像C语言中的短路表达式一样工作,并且会在确定字符串后立即返回结果,例如,即使不比较字符串'a1bbbbbbc','b'和'c'。

  2. ord更好,因为它提供了更大的灵活性,例如仅在“ 0”和“ 5”之间或任何其他范围内的校验数字。例如,如果要编写数字的十六进制表示形式的验证器,则希望字符串的字母仅在“ A”至“ F”范围内。


1
alp_num = [x for x in string.split() if x.isalnum() and re.search(r'\d',x) and 
re.search(r'[a-z]',x)]

print(alp_num)

这将返回其中包含字母和数字的所有字符串。isalpha()返回包含所有数字或所有字符的字符串。


0

这可能不是Python中最好的方法,但是作为Haskeller,这种lambda / map方法对我来说非常有意义,而且非常简短:

anydigit = lambda x: any(map(str.isdigit, x))

当然不需要命名。命名它可以像一样使用anydigit("abc123"),感觉就像我在寻找什么!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.