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


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.