Periksa apakah string berisi angka


193

Sebagian besar pertanyaan yang saya temukan bias pada fakta mereka mencari huruf dalam jumlah mereka, sedangkan saya mencari angka dalam apa yang saya inginkan menjadi string yang tak terhitung jumlahnya. Saya perlu memasukkan string dan memeriksa untuk melihat apakah itu berisi angka dan apakah itu menolaknya.

Fungsi isdigit()hanya kembali Truejika SEMUA karakter adalah angka. Saya hanya ingin melihat apakah pengguna telah memasukkan angka sehingga kalimat seperti "I own 1 dog"atau sesuatu.

Ada ide?

Jawaban:


291

Anda dapat menggunakan anyfungsi, dengan str.isdigitfungsi, seperti ini

>>> def hasNumbers(inputString):
...     return any(char.isdigit() for char in inputString)
... 
>>> hasNumbers("I own 1 dog")
True
>>> hasNumbers("I own no dog")
False

Atau Anda dapat menggunakan Ekspresi Reguler, seperti ini

>>> import re
>>> def hasNumbers(inputString):
...     return bool(re.search(r'\d', inputString))
... 
>>> hasNumbers("I own 1 dog")
True
>>> hasNumbers("I own no dog")
False

Bagaimana dengan angka negatif?
Ray

@ Ray Kemudian RegEx dapat diperpanjang seperti inir'-?\d+'
thefourtheye

15
Bukankah regex asli akan mendeteksi angka negatif?
confused00

1
@ confused00 Tidak, \dakan cocok hanya satu digit di kisaran 0untuk 9.
theouroureye

9
@thefourtheye: -1 masih digit. Ini adalah tanda hubung, diikuti oleh angka '1'
user3183018

49

Anda dapat menggunakan kombinasi dari anydan str.isdigit:

def num_there(s):
    return any(i.isdigit() for i in s)

Fungsi akan kembali Truejika digit ada di string, jika tidak False.

Demo:

>>> king = 'I shall have 3 cakes'
>>> num_there(king)
True
>>> servant = 'I do not have any cakes'
>>> num_there(servant)
False

Tidak perlu membuat daftar sementara, Anda dapat menggunakan ekspresi generator sebagai gantinya hanya dengan menghapus tanda kurung itu.
Matteo Italia

Ah ya, baru sadar bahwa anymenerima ekspresi generator.
aIKid


28

https://docs.python.org/2/library/re.html

Anda sebaiknya menggunakan ekspresi reguler. Jauh lebih cepat.

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 tidak mengembalikan apa pun
pyd

Itu berarti tidak ada yang cocok, ia kembaliNone
zyxue

RE_D = re.compile ('\ d') def has_digits (string): res = RE_D.search (string) return res tidak ada
Raul

8

Anda bisa menerapkan fungsi isdigit () pada setiap karakter di String. Atau Anda bisa menggunakan ekspresi reguler.

Saya juga menemukan Bagaimana cara menemukan satu angka dalam sebuah string dengan Python? dengan cara yang sangat cocok untuk mengembalikan angka. Solusi di bawah ini adalah dari jawaban dalam pertanyaan itu.

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

Kalau tidak:

number = filter(str.isdigit, yourString)

Untuk Informasi lebih lanjut, lihat dokumen regex: http://docs.python.org/2/library/re.html

Sunting: Ini Mengembalikan angka yang sebenarnya, bukan nilai boolean, sehingga jawaban di atas lebih tepat untuk kasus Anda

Metode pertama akan mengembalikan digit pertama dan digit berikutnya berturut-turut. Dengan demikian 1,56 akan dikembalikan sebagai 1. 10.000 akan dikembalikan 10. 10.2020-100-1000 akan dikembalikan sebagai 0.207.

Metode kedua tidak berhasil.

Untuk mengekstrak semua digit, titik, dan koma, dan tidak kehilangan digit non-berturut-turut, gunakan:

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

3

Anda dapat menggunakan metode NLTK untuk itu.

Ini akan menemukan '1' dan 'One' dalam teks:

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

Anda dapat mencapai ini sebagai berikut:

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

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

Menggunakan .isdigit()juga berarti tidak harus menggunakan penanganan pengecualian (coba / kecuali) dalam kasus di mana Anda perlu menggunakan pemahaman daftar (coba / kecuali tidak mungkin di dalam pemahaman daftar).


2

Anda dapat menggunakan rentang dengan hitungan untuk memeriksa berapa kali suatu angka muncul dalam string dengan mencentangnya terhadap rentang:

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

Saya terkejut bahwa tidak ada yang menyebutkan kombinasi anydan map:

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

dalam python 3 itu mungkin yang tercepat di sana (kecuali mungkin untuk regex) adalah karena tidak mengandung loop apa pun (dan aliasing fungsi menghindari mencari di str).

Jangan gunakan itu di python 2 sebagai mapmengembalikan a list, yang merusak anyhubungan arus pendek


2

Bagaimana dengan yang ini?

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
Tolong jangan hanya membuang kode sumber Anda di sini. Bersikap baik dan coba berikan deskripsi yang bagus untuk jawaban Anda, sehingga orang lain akan menyukainya dan meningkatkannya. Lihat: Bagaimana saya menulis jawaban yang baik?
sɐunıɔ ןɐ qɐp

2

Saya akan membuat jawaban @zyxue sedikit lebih eksplisit:

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

yang merupakan solusi dengan tolok ukur tercepat dari solusi yang @zyxue usulkan pada jawabannya.


1

Cara yang lebih mudah untuk diselesaikan adalah sebagai

s = '1dfss3sw235fsf7s'
count = 0
temp = list(s)
for item in temp:
    if(item.isdigit()):
        count = count + 1
    else:
        pass
print count

1
Selamat Datang di Stack Overflow! Tolong jangan hanya membuang kode sumber Anda di sini. Bersikap baik dan coba berikan deskripsi yang bagus untuk jawaban Anda, sehingga orang lain akan menyukainya dan meningkatkannya. Lihat: Bagaimana saya menulis jawaban yang baik?
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)

Kode ini menghasilkan urutan dengan ukuran n yang setidaknya berisi huruf besar, huruf kecil, dan angka. Dengan menggunakan loop sementara, kami telah menjamin acara ini.


Silakan tambahkan penjelasan untuk jawaban Anda
Mastisa

1

anydan orddapat dikombinasikan untuk melayani tujuan seperti yang ditunjukkan di bawah ini.

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

Beberapa poin tentang implementasi ini.

  1. any lebih baik karena bekerja seperti ekspresi hubung singkat dalam Bahasa C dan akan mengembalikan hasil segera setelah itu dapat ditentukan yaitu dalam kasus string 'a1bbbbbbbc' 'b's dan' c's bahkan tidak akan dibandingkan.

  2. ordlebih baik karena memberikan lebih banyak fleksibilitas seperti hanya memeriksa angka antara '0' dan '5' atau rentang lainnya. Sebagai contoh jika Anda menulis validator untuk representasi angka heksadesimal Anda ingin string memiliki huruf dalam rentang 'A' ke 'F' saja.


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)

Ini mengembalikan semua string yang memiliki huruf dan angka di dalamnya. isalpha () mengembalikan string dengan semua digit atau semua karakter.


0

Ini mungkin bukan pendekatan terbaik dengan Python, tetapi sebagai Haskeller, pendekatan lambda / peta ini sangat masuk akal bagi saya dan sangat singkat:

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

Tidak perlu disebutkan namanya tentu saja. Dinamakan itu bisa digunakan seperti anydigit("abc123"), yang terasa seperti apa yang saya cari!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.