วิธีการตรวจสอบว่าสตริงมีองค์ประกอบจากรายการใน Python


217

ฉันมีสิ่งนี้:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

ฉันสงสัยว่าสิ่งใดจะเป็นวิธีที่สง่างามยิ่งกว่าในการทำสิ่งนี้ใน Python (โดยไม่ใช้การวนซ้ำ) ฉันกำลังคิดถึงบางสิ่งเช่นนี้ (เช่นจาก C / C ++) แต่มันไม่ทำงาน:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

แก้ไข: ฉันถูกบังคับให้อธิบายว่าสิ่งนี้แตกต่างกับคำถามด้านล่างซึ่งมีการทำเครื่องหมายว่าซ้ำซ้อนหรือไม่ (ดังนั้นจึงไม่ถูกปิดฉันเดาว่า)

ข้อแตกต่างคือฉันต้องการตรวจสอบว่าสตริงเป็นส่วนหนึ่งของรายการสตริงหรือไม่ในขณะที่คำถามอื่น ๆ กำลังตรวจสอบว่าสตริงจากรายการสตริงเป็นสตริงย่อยของสตริงอื่นหรือไม่ คล้ายกัน แต่ไม่เหมือนกันและมีความหมายเหมือนกันเมื่อคุณกำลังมองหาคำตอบออนไลน์ IMHO คำถามสองข้อนี้กำลังมองหาที่จะแก้ปัญหาตรงข้ามกัน ทางออกสำหรับทั้งคู่กลายเป็นเหมือนเดิม


4
ซ้ำกันที่เป็นไปได้ของการตรวจสอบว่ามีหลายสายในสตริงอื่น
GingerPlusPlus

คำตอบ:


421

ใช้ตัวสร้างพร้อมกับanyวงจรลัดใน True ตัวแรก:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

แก้ไข:ฉันเห็นคำตอบนี้ได้รับการยอมรับจาก OP แม้ว่าวิธีแก้ปัญหาของฉันอาจเป็นวิธี "ดีพอ" สำหรับปัญหาเฉพาะของเขาและเป็นวิธีการทั่วไปที่ดีในการตรวจสอบว่ามีสตริงใด ๆ ในรายการที่พบในสตริงอื่นโปรดทราบว่านี่คือทั้งหมดที่โซลูชันนี้ทำ แต่ไม่ได้ดูแล WHERE สตริงที่พบเช่นในตอนจบของสตริง หากสิ่งนี้มีความสำคัญเช่นเดียวกับกรณีที่มี URL คุณควรพิจารณาคำตอบของ @Wladimir Palant หรือคุณเสี่ยงที่จะได้รับผลบวกปลอม


1
นี่คือสิ่งที่ฉันกำลังมองหา ในกรณีของฉันมันไม่สำคัญว่าในสตริงเป็นส่วนขยาย ขอบคุณ
pootzko

ข้อเสนอแนะที่ดี ใช้ตัวอย่างนี้นี่คือวิธีที่ฉันตรวจสอบว่าข้อโต้แย้งใด ๆ ตรงกับความช่วยเหลือที่รู้จักกันดี: ใด ๆ ([x.lower () ใน ['-?', '- h', '- ช่วย', '/ h '] สำหรับ x ใน sys.argv [1:]])
AX Labs

@ AX-Labs ที่ใช้ความเข้าใจในรายการanyจะปฏิเสธผลบวกที่อาจเกิดขึ้นจากการลัดวงจรเนื่องจากรายการทั้งหมดจะต้องถูกสร้างขึ้นในทุกกรณี หากคุณใช้นิพจน์ที่ไม่มีเครื่องหมายวงเล็บเหลี่ยม ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])) x.lower() in [...]จะมีการประเมินส่วนหนึ่งจนกว่าจะพบค่าจริง
Lauritz V. Thaulow

5
และถ้าฉันอยากรู้ว่า ext คืออะไรเมื่อใด () คืนค่า True?
Peter Senna

@PeterSenna: any()จะส่งกลับจริงหรือเท็จเท่านั้น แต่ดูคำตอบที่เข้าใจรายการ @psun ด้านล่างด้วยการปรับเปลี่ยนนี้:print [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
อันนี้ฉลาด - ฉันไม่รู้ว่าทูเปิลสามารถทำสิ่งนั้นได้! แต่มันจะใช้ได้ก็ต่อเมื่อซับสตริงของคุณถูกยึดไว้ที่ปลายด้านหนึ่งของสตริง
Dannid

3
วิธีที่ยอดเยี่ยม ฉันแค่หวังว่าจะมีบางอย่างเช่น "มีอยู่" แทนที่จะเป็นแค่จุดเริ่มต้นหรือจุดสิ้นสุด
BrDaHa

@BrDaHa คุณสามารถใช้ 'ใน' สำหรับมี ถ้า 'string' อยู่ในรายการ:
Shekhar Samanta

@ShekharSamanta แน่นอน แต่นั่นไม่ได้แก้ปัญหาการตรวจสอบว่าหนึ่งในหลายสิ่งที่อยู่ในสตริงซึ่งเป็นคำถามเดิมเกี่ยวกับ
BrDaHa

ใช่ในกรณีที่เราสามารถใช้: ถ้ามี (องค์ประกอบใน string.split ('ใด ๆ delmiter') สำหรับองค์ประกอบในรายการ) และสำหรับสตริงถ้ามี (องค์ประกอบในสตริงสำหรับองค์ประกอบในรายการ)
Shekhar Samanta

21

เป็นการดีกว่าที่จะแยกวิเคราะห์ URL อย่างถูกต้องวิธีนี้คุณสามารถจัดการhttp://.../file.doc?fooและhttp://.../foo.doc/file.exeถูกต้องได้

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

ใช้รายการความเข้าใจหากคุณต้องการโซลูชันบรรทัดเดียว รหัสต่อไปนี้จะคืนค่ารายการที่มี url_string เมื่อมีนามสกุล. doc, .pdf และ. xls หรือส่งคืนรายการเปล่าเมื่อไม่มีส่วนขยาย

print [url_string for extension in extensionsToCheck if(extension in url_string)]

หมายเหตุ: นี่เป็นเพียงการตรวจสอบว่ามันมีหรือไม่และไม่เป็นประโยชน์เมื่อมีใครต้องการที่จะแยกคำที่ตรงกับนามสกุล


นี่เป็นวิธีที่อ่านได้มากกว่าanyคำตอบมันเป็นหนึ่งในคำตอบที่ดีที่สุดสำหรับคำถามนั้นในความคิดของฉัน
Dmitry Verhoturov

อันนี้ดีกว่าการany()แก้ปัญหาในความคิดของฉันเพราะมันสามารถเปลี่ยนแปลงเพื่อส่งกลับค่าการจับคู่ที่เฉพาะเจาะจงเช่นกัน: print [extension for extension in extensionsToCheck if(extension in url_string)](ดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติมและวิธีการแยกคำที่ตรงกันเช่นเดียวกับรูปแบบจาก url_string)
Dannid

2

ตรวจสอบว่ามันตรงกับ regex นี้:

'(\.pdf$|\.doc$|\.xls$)'

หมายเหตุ: หากส่วนขยายของคุณไม่ได้อยู่ท้าย URL ให้ลบ$ตัวอักษร แต่จะทำให้มันอ่อนลงเล็กน้อย


1
มันคือ URL ถ้ามีสตริงการสืบค้นล่ะ
Wladimir Palant

นำเข้าอีกครั้งค้นหา (รูปแบบ your_string)
juankysmith

ในขณะที่คำตอบนี้ใช้ได้กับกรณีที่ระบุ แต่ไม่สามารถปรับขนาดได้หรือทั่วไป คุณต้องใช้ regex แบบยาวสำหรับทุกรูปแบบที่คุณต้องการจับคู่
Dannid

1

นี่คือตัวแปรของคำตอบความเข้าใจในรายการที่กำหนดโดย @psun

โดยการเปลี่ยนค่าเอาต์พุตคุณสามารถแยกรูปแบบการจับคู่ออกจากรายการความเข้าใจ (จริง ๆ แล้วไม่สามารถทำได้ด้วยany()วิธีการของ @ Lauritz-v-Thaulow)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

[ '.doc'] `

คุณสามารถแทรกนิพจน์ปกติเพิ่มเติมหากคุณต้องการรวบรวมข้อมูลเพิ่มเติมเมื่อรู้รูปแบบที่ตรงกัน (ซึ่งอาจเป็นประโยชน์เมื่อรายการรูปแบบที่อนุญาตยาวเกินไปที่จะเขียนลงในรูปแบบ regex เดียว)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

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