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


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.