ตรวจสอบว่าสตริงมีตัวเลขหรือไม่


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
regex ดั้งเดิมจะไม่ตรวจจับตัวเลขลบหรือไม่
สับสน

1
@ confused00 Nope, \dจะตรงกับเพียงหลักเดียวในช่วงที่จะ0 9
thefourtheye

9
@thourourtheye: -1 ยังคงเป็นตัวเลข มันเป็นเส้นประตามด้วยตัวเลข '1'
user3183018

50

คุณสามารถใช้การรวมกันของanyและstr.isdigit:

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

ฟังก์ชั่นจะกลับมาถ้าหลักที่มีอยู่ในสตริงมิฉะนั้นTrueFalse

การสาธิต:

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

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

ส่งคืนจริงถ้าตัวละครทั้งหมดในสตริงเป็นตัวอักษรและมีอย่างน้อยหนึ่งตัวอักษรเท็จอย่างอื่น


8
มีอักขระประเภทอื่นที่ไม่ใช่ตัวอักษรและตัวเลข - เช่น'_'.isalpha()เป็นเท็จ
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 (สตริง): res = RE_D.search (สตริง) res ส่งคืนความต้านทานไม่มี
Raul

8

คุณสามารถใช้ฟังก์ชั่น isdigit () กับตัวละครทุกตัวใน String หรือคุณสามารถใช้การแสดงออกปกติ

นอกจากนี้ฉันพบฉันจะค้นหาหมายเลขหนึ่งในสตริงใน Python ได้อย่างไร ด้วยวิธีที่เหมาะสมมากในการส่งคืนตัวเลข การแก้ปัญหาด้านล่างมาจากคำตอบในคำถามนั้น

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

อีกวิธีหนึ่งคือ:

number = filter(str.isdigit, yourString)

สำหรับข้อมูลเพิ่มเติมดูที่ regex docu: 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 อาจเป็นวิธีที่เร็วที่สุด (ยกเว้นบางทีสำหรับ regexes) เนื่องจากไม่มีการวนซ้ำใด ๆ (และการใช้ชื่อแทนฟังก์ชันเพื่อหลีกเลี่ยงการค้นหาใน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
ยินดีต้อนรับสู่ Stack Overflow! โปรดอย่าเพิ่งโยนซอร์สโค้ดของคุณที่นี่ เป็นคนดีและพยายามให้คำอธิบายที่ดีกับคำตอบของคุณเพื่อที่คนอื่นจะชอบและโหวตขึ้น ดู: ฉันจะเขียนคำตอบที่ดีได้อย่างไร
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 ซึ่งอย่างน้อยมีตัวพิมพ์ใหญ่ตัวพิมพ์เล็กและตัวเลข ด้วยการใช้วงวนขณะที่เรารับประกันเหตุการณ์นี้


โปรดเพิ่มคำอธิบายให้กับคำตอบของคุณ
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 ดีกว่าเพราะมันใช้งานได้เช่นการแสดงออกของการลัดวงจรในภาษา C และจะส่งคืนผลลัพธ์ทันทีที่สามารถกำหนดได้เช่นในกรณีของสตริง 'a1bbbbbbbc' 'b's และ' 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")ซึ่งรู้สึกเหมือนสิ่งที่ฉันกำลังมองหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.