Проверить, содержит ли строка число

Большинство вопросов, которые я нашел, основаны на том факте, что они ищут буквы в своих числах, тогда как я ищу числа в том, что я хотел бы быть бесчисленной строкой. Мне нужно ввести строку и проверить, содержит ли она какие-либо числа и не отклоняет ли она ее.

Функция isdigit() возвращает True только в том случае, если ВСЕ символы являются числами. Я просто хочу посмотреть, ввел ли пользователь число, например, предложение типа "I own 1 dog" или что-то в этом роде.

Любые идеи?


person DonnellyOverflow    schedule 08.11.2013    source источник


Ответы (18)


Вы можете использовать функцию 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
person thefourtheye    schedule 08.11.2013
comment
А отрицательные числа? - person Ray; 25.02.2016
comment
@Ray Тогда RegEx можно расширить следующим образом r'-?\d+' - person thefourtheye; 25.02.2016
comment
Разве исходное регулярное выражение все равно не обнаружит отрицательные числа? - person confused00; 21.07.2016
comment
@confused00 Нет, \d будет соответствовать только одной цифре в диапазоне от 0 до 9. - person thefourtheye; 26.11.2016
comment
@thefourtheye: -1 все еще цифра. Это тире, за которым следует цифра «1». - person user3183018; 27.02.2017
comment
@thefourtheye вы не учли, есть ли цифра в конце строки с одним или несколькими пробелами. вы не сможете обнаружить цифру. так что вы можете сделать это с char.strip().isdigit() - person Frank AK; 13.07.2018

Вы можете использовать комбинацию any и str.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
person aIKid    schedule 08.11.2013
comment
Нет необходимости создавать временный список, вместо этого вы можете использовать выражение генератора, просто удалив эти квадратные скобки. - person Matteo Italia; 08.11.2013
comment
Ах да, только что понял, что any принимает выражения генератора. - person aIKid; 08.11.2013

use

str.isalpha() 

Ссылка: https://docs.python.org/2/library/stdtypes.html#str.isalpha

Возвращает true, если все символы в строке являются буквенными и есть хотя бы один символ, иначе false.

person K246    schedule 28.06.2015
comment
Существуют и другие типы символов, кроме буквенных и цифровых, например, '_'.isalpha() — это False. - person lvc; 28.06.2015
comment
Такие символы, как «ç» и «ñ», не распознаются. Например, символ «œ» присутствует в текстах на среднеанглийском языке. - person Eduardo Freitas; 09.02.2021

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
person zyxue    schedule 06.08.2015
comment
f3 ничего не возвращает - person pyd; 04.03.2018
comment
Это означает, что совпадения нет, он возвращает None - person zyxue; 04.03.2018
comment
RE_D = re.compile('\d') def has_digits(string): res = RE_D.search(string) return res не None - person Raul; 10.01.2020

Вы можете применить функцию 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)
person Haini    schedule 08.11.2013

Вы можете сделать это следующим образом:

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

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

Использование .isdigit() также означает, что не нужно прибегать к обработке исключений (try/except) в тех случаях, когда вам нужно использовать понимание списка (try/except невозможно внутри понимания списка).

person olisteadman    schedule 15.03.2018
comment
Это проверяет, являются ли все символы цифрами, а не принадлежностью к строке. - person OneCricketeer; 25.03.2021

Вы можете использовать для этого метод 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.')
person Mahendra S. Chouhan    schedule 06.10.2017

Вы можете использовать диапазон со счетчиком, чтобы проверить, сколько раз число появляется в строке, сверив его с диапазоном:

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
person pedmindset    schedule 29.09.2017
comment
Это кажется очень неэффективным. Для каждого символа вы зацикливаете 0-10, затем линейно сканируете строку, проходя символы более одного раза... Просто используйте isdigit() - person OneCricketeer; 25.03.2021

Я удивлен, что никто не упомянул эту комбинацию any и map:

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

в python 3 он, вероятно, самый быстрый (за исключением, возможно, регулярных выражений), потому что он не содержит никакого цикла (и псевдоним функции позволяет избежать поиска в str).

Не используйте это в python 2, так как map возвращает list, что прерывает короткое замыкание any

person Jean-François Fabre    schedule 20.09.2018

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, мы гарантировали это событие.

person Mehran Attar    schedule 05.10.2018
comment
Пожалуйста, добавьте объяснение к вашему ответу - person mastisa; 05.10.2018

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».

person ViFI    schedule 24.07.2019

Что насчет этого?

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
person aga    schedule 08.11.2013
comment
Пожалуйста, не бросайте сюда свой исходный код. Будьте милы и постарайтесь дать хорошее описание своему ответу, чтобы он понравился другим и проголосовал за него. См.: Как написать хороший ответ? - person sɐunıɔןɐqɐp; 15.06.2018

Я сделаю ответ @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 в ответе.

person Raul    schedule 10.01.2020

Это, вероятно, не лучший подход в Python, но как Haskeller этот подход лямбда/карта показался мне идеальным и очень коротким:

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

Имя конечно не надо. Названный он может использоваться как anydigit("abc123"), что похоже на то, что я искал!

person Oscar South    schedule 21.05.2020

Более простой способ решить, как

s = '1dfss3sw235fsf7s'
count = 0
temp = list(s)
for item in temp:
    if(item.isdigit()):
        count = count + 1
    else:
        pass
print count
person BlizZard    schedule 15.06.2018
comment
Добро пожаловать в Stack Overflow! Пожалуйста, не бросайте сюда свой исходный код. Будьте милы и постарайтесь дать хорошее описание своему ответу, чтобы он понравился другим и проголосовал за него. См.: Как написать хороший ответ? - person sɐunıɔןɐqɐp; 15.06.2018

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() возвращает строку со всеми цифрами или всеми символами.

person Sai ram    schedule 04.11.2019

Это тоже сработает.

if any(i.isdigit() for i in s):
    print("True")
person laplace    schedule 18.12.2020

Кроме того, вы можете использовать регулярное выражение findall. Это более общее решение, поскольку оно добавляет больше контроля над длиной числа. Это может быть полезно в тех случаях, когда вам требуется число минимальной длины.

s = '67389kjsdk' 
contains_digit = len(re.findall('\d+', s)) > 0
person easf    schedule 14.12.2020
comment
Проблема ясна и не требует контроля над длиной числа. Вы здесь отвечаете на другой вопрос. Пожалуйста, проголосуйте или напишите комментарий, если у вас есть предложения по улучшению. - person BcK; 14.12.2020
comment
Ты прав. Спасибо за совет. - person easf; 14.12.2020