Перевірте, чи містить рядок число


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'
користувач3183018

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

Не потрібно створювати тимчасовий список, ви можете використовувати генераторний вираз замість цього, просто видаливши ці квадратні дужки.
Маттео Італія

Ага так, щойно зрозумів, що anyприймає генераторні вирази.
aIKid

30

використання

str.isalpha () 

Посилання: https://docs.python.org/2/library/stdtypes.html#str.isalpha

Повернути істину, якщо всі символи в рядку є алфавітними та є принаймні один символ, інакше помилковий.


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 is not None
Раул

8

Ви можете застосувати функцію isdigit () до кожного символу в рядку. Або ви можете використовувати регулярні вирази.

Також я знайшов Як знайти одне число в рядку в Python? з дуже підходящими способами повернення номерів. Наведене нижче рішення - з відповіді на це питання.

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

Як варіант:

number = filter(str.isdigit, yourString)

Для отримання додаткової інформації погляньте на doge regex: 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», так і «Один»:

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, ми гарантували цю подію.


Будь ласка, додайте пояснення до своєї відповіді
Мастіса

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, цей підхід лямбда-карти мав для мене ідеальний сенс і дуже короткий:

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

Звичайно, не потрібно називати його. Названий він міг би бути використаний як anydigit("abc123"), який відчуває, що я шукав!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.