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


196

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

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

Любые идеи?

Ответы:


295

Вы можете использовать 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 Тогда RegEx можно продлить вот такr'-?\d+'
thefourtheye

15
Разве оригинальное регулярное выражение не обнаружит отрицательные числа в любом случае?
confused00

1
@ confused00 Нет, \dбудет соответствовать только одна цифра в диапазоне 0до 9.
thefourtheye

9
@thefourtheye: -1 все еще цифра. Это тире, за которым следует цифра «1»
user3183018

50

Вы можете использовать комбинацию 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

Не нужно создавать временный список, вместо этого вы можете использовать выражение генератора, просто удалив эти квадратные скобки.
Matteo Italia

Ах да, только что понял, что anyпринимает выражения генератора.
aIKid

30

использование

str.isalpha () 

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

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


8
Существуют и другие типы символов, кроме буквенных и числовых, например '_'.isalpha()False.
LVC

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) return res - это не None
Рауль

8

Вы можете применить функцию isdigit () к каждому символу в строке. Или вы можете использовать регулярные выражения.

Также я нашел Как найти одно число в строке в Python? с очень подходящими способами вернуть числа. Решение ниже от ответа на этот вопрос.

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

В качестве альтернативы:

number = filter(str.isdigit, yourString)

Для получения дополнительной информации ознакомьтесь с документом regex: http://docs.python.org/2/library/re.html.

Изменить: Возвращает действительные числа, а не логическое значение, поэтому приведенные выше ответы более верны для вашего случая.

Первый метод возвращает первую цифру и последующие последовательные цифры. Таким образом, 1.56 будет возвращено как 1. 10000 будет возвращено как 10. 0207-100-1000 будет возвращено как 0207.

Второй метод не работает.

Чтобы извлечь все цифры, точки и запятые и не потерять непоследовательные цифры, используйте:

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

3

Вы можете использовать метод 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.')

2

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

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

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

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


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

Я удивлен, что никто не упомянул эту комбинацию anyи 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
Добро пожаловать в стек переполнения! Пожалуйста, не бросайте свой исходный код здесь. Будьте добры и постарайтесь дать хорошее описание вашему ответу, чтобы другим понравилось, и проголосуйте за него. Смотрите: Как мне написать хороший ответ?
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 лучше, потому что он работает как выражение короткого замыкания в языке Си и вернет результат, как только он может быть определен, т. е. в случае строки '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, этот подход лямбда / карта имел для меня смысл и очень короткий:

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.