Kiểm tra xem một chuỗi có chứa một số không


193

Hầu hết các câu hỏi tôi tìm thấy đều thiên về thực tế họ đang tìm kiếm các chữ cái trong số của họ, trong khi tôi đang tìm kiếm các số trong những gì tôi muốn là một chuỗi vô số. Tôi cần phải nhập một chuỗi và kiểm tra xem nó có chứa bất kỳ số nào không và liệu nó có từ chối nó không.

Hàm isdigit()chỉ trả về Truenếu TẤT CẢ các ký tự là số. Tôi chỉ muốn xem liệu người dùng đã nhập một số để một câu như thế "I own 1 dog"hay gì đó.

Có ý kiến ​​gì không?

Câu trả lời:


291

Bạn có thể sử dụng anychức năng, với str.isdigitchức năng, như thế này

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

Ngoài ra, bạn có thể sử dụng Biểu thức chính quy, như thế này

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

Còn số âm thì sao?
Ray

@Ray Sau đó, RegEx có thể được mở rộng như thế nàyr'-?\d+'
thefourtheye

15
Liệu regex ban đầu có phát hiện ra các số âm không?
bối

1
@ confused00 Nope, \dsẽ phù hợp với chỉ một chữ số duy nhất trong phạm vi 0đến 9.
thefourtheye

9
@thefourtheye: -1 vẫn là một chữ số. Đó là một dấu gạch ngang, theo sau là chữ số '1'
user3183018

49

Bạn có thể sử dụng kết hợp anystr.isdigit:

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

Hàm sẽ trả về Truenếu một chữ số tồn tại trong chuỗi, nếu không False.

Bản giới thiệu:

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

Không cần tạo danh sách tạm thời, bạn có thể sử dụng biểu thức trình tạo thay vì chỉ bằng cách xóa các dấu ngoặc vuông đó.
Matteo Italia

Ah yeah, chỉ cần nhận ra rằng anychấp nhận biểu thức máy phát điện.
aIKid

30

sử dụng

str.alupha () 

Tham chiếu: https://docs.python.org/2/l Library / stdtypes.html#str.alupha

Trả về true nếu tất cả các ký tự trong chuỗi là chữ cái và có ít nhất một ký tự, sai khác.


8
Có các loại ký tự khác ngoài chữ cái và số - ví dụ: '_'.isalpha()là Sai.
lvc

28

https://docs.python.org/2/l Library / re.html

Bạn nên sử dụng biểu thức thường xuyên. Nó nhanh hơn nhiều.

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 không trả lại bất cứ điều gì
pyd

Điều đó có nghĩa là không có trận đấu nào, nó sẽ trở lạiNone
zyxue

RE_D = re.compile ('\ d') def has_digits (chuỗi): res = RE_D.search (chuỗi) return res không phải là Không có
Raul

8

Bạn có thể áp dụng hàm isdigit () trên mỗi ký tự trong Chuỗi. Hoặc bạn có thể sử dụng các biểu thức thông thường.

Ngoài ra tôi tìm thấy Làm cách nào để tìm một số trong chuỗi trong Python? với những cách rất phù hợp để trả về số. Giải pháp dưới đây là từ câu trả lời trong câu hỏi đó.

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

Cách khác:

number = filter(str.isdigit, yourString)

Để biết thêm thông tin, hãy xem regex docu: http://docs.python.org/2/l Library / re.html

Chỉnh sửa: Điều này Trả về số thực tế, không phải giá trị boolean, vì vậy các câu trả lời ở trên chính xác hơn cho trường hợp của bạn

Phương thức đầu tiên sẽ trả về chữ số đầu tiên và các chữ số liên tiếp tiếp theo. Do đó, 1.56 sẽ được trả về là 1. 10.000 sẽ được trả về là 10. 0207-100-1000 sẽ được trả về là 0207.

Phương pháp thứ hai không hoạt động.

Để trích xuất tất cả các chữ số, dấu chấm và dấu phẩy và không mất các chữ số không liên tiếp, hãy sử dụng:

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

3

Bạn có thể sử dụng phương pháp NLTK cho nó.

Điều này sẽ tìm thấy cả '1' và 'Một' trong văn bản:

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

Bạn có thể thực hiện điều này như sau:

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

https://docs.python.org/2/l Library / stdtypes.html # str. thẩmigit

Sử dụng .isdigit()cũng có nghĩa là không phải dùng đến xử lý ngoại lệ (thử / ngoại trừ) trong trường hợp bạn cần sử dụng khả năng hiểu danh sách (thử / ngoại trừ không thể có trong cách hiểu danh sách).


2

Bạn có thể sử dụng phạm vi với số đếm để kiểm tra số lần xuất hiện trong chuỗi bằng cách kiểm tra số đó so với phạm vi:

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

Tôi ngạc nhiên khi không ai nhắc đến sự kết hợp này anymap:

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

trong python 3, nó có lẽ là nhanh nhất ở đó (ngoại trừ có thể là regexes) là vì nó không chứa bất kỳ vòng lặp nào (và bí danh hàm tránh việc tìm kiếm nó str).

Không sử dụng điều đó trong python 2 khi maptrả về a list, làm đứt anymạch


2

Cái này thì sao?

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
Xin đừng ném mã nguồn của bạn ở đây. Hãy tử tế và cố gắng đưa ra một mô tả hay cho câu trả lời của bạn, để những người khác sẽ thích nó và nâng cao nó. Xem: Làm thế nào để tôi viết một câu trả lời tốt?
sɐunıɔ qɐp

2

Tôi sẽ làm cho câu trả lời @zyxue rõ ràng hơn một chút:

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

đó là giải pháp có điểm chuẩn nhanh nhất từ ​​các giải pháp mà @zyxue đề xuất trên câu trả lời.


1

Cách đơn giản hơn để giải quyết là

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

1
Chào mừng bạn đến với Stack Overflow! Xin đừng ném mã nguồn của bạn ở đây. Hãy tử tế và cố gắng đưa ra một mô tả hay cho câu trả lời của bạn, để những người khác sẽ thích nó và nâng cao nó. Xem: Làm thế nào để tôi viết một câu trả lời tốt?
sunıɔ 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)

Mã này tạo ra một chuỗi có kích thước n ít nhất chứa chữ hoa, chữ thường và chữ số. Bằng cách sử dụng vòng lặp while, chúng tôi đã đảm bảo sự kiện này.


Vui lòng thêm lời giải thích cho câu trả lời của bạn
Mastisa

1

anyordcó thể được kết hợp để phục vụ mục đích như hình dưới đây.

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

Một vài điểm về việc thực hiện này.

  1. any tốt hơn bởi vì nó hoạt động giống như biểu thức ngắn mạch trong Ngôn ngữ C và sẽ trả về kết quả ngay khi có thể xác định, tức là trong trường hợp chuỗi 'a1bbbbbbc' 'b' và 'c' thậm chí sẽ không được so sánh.

  2. ordlà tốt hơn bởi vì nó cung cấp sự linh hoạt hơn như các số kiểm tra chỉ trong khoảng từ '0' đến '5' hoặc bất kỳ phạm vi nào khác. Ví dụ: nếu bạn viết một trình xác nhận cho biểu diễn số thập lục phân, bạn sẽ muốn chuỗi có bảng chữ cái trong phạm vi 'A' đến '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)

Điều này trả về tất cả các chuỗi có cả bảng chữ cái và số trong đó. isalpha () trả về chuỗi có tất cả các chữ số hoặc tất cả các ký tự.


0

Đây có lẽ không phải là cách tiếp cận tốt nhất trong Python, nhưng với tư cách là một Haskeller, cách tiếp cận lambda / map này có ý nghĩa hoàn hảo với tôi và rất ngắn gọn:

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

Tất nhiên không cần phải nêu tên. Đặt tên nó có thể được sử dụng như thế anydigit("abc123"), cảm giác như những gì tôi đang tìm kiếm!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.