【问题标题】:Check if a string contains a number检查字符串是否包含数字
【发布时间】:2013-11-20 11:25:46
【问题描述】:

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

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

有什么想法吗?

【问题讨论】:

    标签: python string


    【解决方案1】:

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

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

    您也可以使用正则表达式,像这样

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

    【讨论】:

    • 负数呢?
    • @Ray 那么RegEx可以像这样扩展r'-?\d+'
    • 原始正则表达式不会检测到负数吗?
    • @confused00 不,\d 将仅匹配 09 范围内的单个数字。
    • @thefourtheye:-1 仍然是一个数字。它是一个破折号,后跟数字“1”
    【解决方案2】:

    另外,您可以使用正则表达式 findall。这是一个更通用的解决方案,因为它增加了对数字长度的更多控制。如果您需要一个长度最短的数字,这可能会有所帮助。

    s = '67389kjsdk' 
    contains_digit = len(re.findall('\d+', s)) > 0
    

    【讨论】:

    • 问题很清楚,并没有说明需要控制数字的长度。你在这里回答另一个问题。如果您有改进建议,请点赞或发表评论。
    【解决方案3】:

    这也可以。

    if any(i.isdigit() for i in s):
        print("True")
    

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

        我会让@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在答案中提出的解决方案中基准最快的解决方案。

        【讨论】:

          【解决方案6】:

          这个呢?

          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
          

          【讨论】:

          • 请不要把你的源代码扔在这里。友善一点,并尝试对您的答案进行漂亮的描述,以便其他人会喜欢并支持它。见:How do I write a good answer?
          【解决方案7】:
          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() 返回全数字或全字符的字符串。

          【讨论】:

            【解决方案8】:

            anyord 可以组合起来达到如下所示的目的。

            >>> 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's 和 'c's 的情况下甚至不会比较。

            2. ord 更好,因为它提供了更大的灵活性,例如仅在“0”和“5”之间或任何其他范围内的支票号码。例如,如果您要为数字的十六进制表示编写验证器,您可能希望字符串只有在“A”到“F”范围内的字母。

            【讨论】:

              【解决方案9】:

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

              我还发现How do I find one number in a string in 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)
              

              【讨论】:

                【解决方案10】:
                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 循环,我们保证了这个事件。

                【讨论】:

                • 请在您的回答中添加解释
                【解决方案11】:

                我很惊讶没有人提到anymap 的组合:

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

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

                不要在 python 2 中使用它,因为 map 返回一个 list,它会破坏 any 短路

                【讨论】:

                  【解决方案12】:

                  您可以使用 range 和 count 来检查一个数字在字符串中出现的次数,方法是根据范围检查它:

                  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
                  

                  【讨论】:

                  • 这似乎非常不理想。对于每个字符,您循环 0-10,然后线性扫描字符串,多次遍历字符...只需使用 isdigit()
                  【解决方案13】:

                  你可以使用 NLTK 方法。

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

                  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.')
                  

                  【讨论】:

                    【解决方案14】:

                    更简单的解决方法如下

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

                    【讨论】:

                    • 欢迎来到 Stack Overflow!请不要把你的源代码扔在这里。友善一点,并尝试对您的答案进行漂亮的描述,以便其他人会喜欢并支持它。见:How do I write a good answer?
                    【解决方案15】:

                    您可以按如下方式完成:

                    if a_string.isdigit(): do_this() else: do_that()

                    https://docs.python.org/2/library/stdtypes.html#str.isdigit

                    使用.isdigit() 也意味着在需要使用列表解析的情况下不必诉诸异常处理(try/except)(在列表解析中无法使用try/except)。

                    【讨论】:

                    • 这会检查所有字符是否都是数字,而不是字符串中的成员
                    【解决方案16】:

                    您可以使用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
                    

                    【讨论】:

                    • 无需创建临时列表,您可以使用生成器表达式,只需删除方括号即可。
                    • 啊,是的,刚刚意识到any 接受生成器表达式。
                    【解决方案17】:

                    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 没有返回任何东西
                    • 表示没有匹配,返回None
                    • RE_D = re.compile('\d') def has_digits(string): res = RE_D.search(string) return res is not None
                    【解决方案18】:

                    使用

                    str.isalpha() 

                    参考:https://docs.python.org/2/library/stdtypes.html#str.isalpha

                    如果字符串中的所有字符都是字母并且存在,则返回 true 至少为一个字符,否则为假。

                    【讨论】:

                    • 除了字母和数字之外还有其他类型的字符 - 例如,'_'.isalpha() 为 False。
                    • 无法识别诸如“ç”和“ñ”之类的字符。例如,字符“œ”出现在中古英语文本中。
                    猜你喜欢
                    • 1970-01-01
                    • 2015-02-07
                    • 2010-12-19
                    • 1970-01-01
                    • 2022-06-30
                    • 2011-11-09
                    • 2013-05-18
                    相关资源
                    最近更新 更多