ฉันจะรับทุกอย่างก่อน a: ในสตริง Python ได้อย่างไร


110

ฉันกำลังมองหาวิธีรับตัวอักษรทั้งหมดในสตริงก่อน a: แต่ฉันไม่รู้ว่าจะเริ่มจากตรงไหน ฉันจะใช้ regex หรือไม่ ถ้าเป็นอย่างไร

string = "Username: How are you today?"

ใครช่วยแสดงตัวอย่างสิ่งที่ฉันทำได้

คำตอบ:


187

เพียงแค่ใช้splitฟังก์ชัน จะส่งคืนรายการดังนั้นคุณสามารถเก็บองค์ประกอบแรกไว้ได้:

>>> s1.split(':')
['Username', ' How are you today?']
>>> s1.split(':')[0]
'Username'

13
ทั้งจำกัด การแยกหรือในกรณีนี้ - ใช้s1.partition(':')[0]
จอนเคลเมนท์

ขอบคุณสิ่งนี้มีประโยชน์และให้ข้อมูลมาก นอกจากนี้ยังช่วยขอบคุณมาก!
0Cool

3
อย่าใช้การแยกเนื่องจากกำลังประมวลผล ":" ทั้งหมดและสร้างอาร์เรย์แบบเต็มไม่เหมาะสำหรับสตริงที่ยาวขึ้น ดูวิธีการใช้ดัชนีของ @ Hackaholic เพียงแค่นั้นยังแนะนำ regex ซึ่งไม่ได้ผลอย่างชัดเจน นอกจากนี้ยังต้องมีตัวเลือก python เพื่อดำเนินการมาตรฐานของ. substringBefore () ซึ่งอิงดัชนี และรูปแบบต่างๆเช่น. SubstringBeforeLast () ฯลฯ ควรมีเพื่อความสะดวก (ไม่ควรใช้รหัสซ้ำ) สังเกตเห็นประเด็นเกี่ยวกับพาร์ติชัน - ใช่การประมวลผลน้อยลงหลังจาก ':' แต่ยังคงส่งกลับ <class 'tuple'>: ('1', ':', '2: 3') แทนที่จะเป็น '1'
arntg

51

ใช้index:

>>> string = "Username: How are you today?"
>>> string[:string.index(":")]
'Username'

ดัชนีจะให้ตำแหน่งของ:สตริงจากนั้นคุณสามารถแบ่งได้

หากคุณต้องการใช้ regex:

>>> import re
>>> re.match("(.*?):",string).group()
'Username'                       

match จับคู่จากจุดเริ่มต้นของสตริง

คุณยังสามารถใช้ itertools.takewhile

>>> import itertools
>>> "".join(itertools.takewhile(lambda x: x!=":", string))
'Username'

4
วิธีนี้ (string [: string.index (":")]) น่าจะสะอาดกว่าการแยก
Damien

เพื่อความรวดเร็วอย่าใช้ regex - ใช้ตัวเลือกดัชนีแรกที่กล่าวถึงที่นี่ Regex ไม่มีประสิทธิภาพอย่างชัดเจน นอกจากนี้ยังต้องมีตัวเลือก python เพื่อดำเนินการมาตรฐานของ. substringBefore () ซึ่งอิงดัชนี และรูปแบบต่างๆเช่น. SubstringBeforeLast () ฯลฯ ควรมีเพื่อความสะดวก (ไม่ควรใช้รหัสซ้ำ) แนะนำให้อัปเดตคำตอบนี้เพื่ออธิบายว่าเหตุใดดัชนีจึงทำงานได้ดีขึ้นและเหตุใดจึงควรใช้วิธีนี้กับแนวทางอื่น ๆ ซึ่งรวมถึงวิธีการที่ได้รับการโหวตสูงกว่าในการตอบสนองของเฟรดทันทินี
arntg

1
หากไม่มีอยู่ดัชนีจะล้มเหลว
Marc

ใน regex: re.match ("(. *?):", string) .group () ทำไมเราต้องมี "?" ไม่ควรทำ re.match ("(. *):", string) .group ()
David Gladson

21

คุณไม่ต้องการregexสิ่งนี้

>>> s = "Username: How are you today?"

คุณสามารถใช้splitวิธีการแยกสตริงบน':'อักขระ

>>> s.split(':')
['Username', ' How are you today?']

และตัดองค์ประกอบ[0]เพื่อให้ได้ส่วนแรกของสตริง

>>> s.split(':')[0]
'Username'

10

ฉันได้เปรียบเทียบเทคนิคต่างๆเหล่านี้ภายใต้ Python 3.7.0 (IPython)

TLDR

  • เร็วที่สุด (เมื่อcรู้จักสัญลักษณ์แยก): regex ที่คอมไพล์ไว้ล่วงหน้า
  • ที่เร็วที่สุด (อื่น ๆ s.partition(c)[0]):
  • ปลอดภัย (เช่นเมื่อใดที่cอาจไม่อยู่ในs): พาร์ติชันแยก
  • ไม่ปลอดภัย: ดัชนี regex

รหัส

import string, random, re

SYMBOLS = string.ascii_uppercase + string.digits
SIZE = 100

def create_test_set(string_length):
    for _ in range(SIZE):
        random_string = ''.join(random.choices(SYMBOLS, k=string_length))
        yield (random.choice(random_string), random_string)

for string_length in (2**4, 2**8, 2**16, 2**32):
    print("\nString length:", string_length)
    print("  regex (compiled):", end=" ")
    test_set_for_regex = ((re.compile("(.*?)" + c).match, s) for (c, s) in test_set)
    %timeit [re_match(s).group() for (re_match, s) in test_set_for_regex]
    test_set = list(create_test_set(16))
    print("  partition:       ", end=" ")
    %timeit [s.partition(c)[0] for (c, s) in test_set]
    print("  index:           ", end=" ")
    %timeit [s[:s.index(c)] for (c, s) in test_set]
    print("  split (limited): ", end=" ")
    %timeit [s.split(c, 1)[0] for (c, s) in test_set]
    print("  split:           ", end=" ")
    %timeit [s.split(c)[0] for (c, s) in test_set]
    print("  regex:           ", end=" ")
    %timeit [re.match("(.*?)" + c, s).group() for (c, s) in test_set]

ผล

String length: 16
  regex (compiled): 156 ns ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.3 µs ± 430 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            26.1 µs ± 341 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.3 µs ± 835 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 256
  regex (compiled): 167 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  index:            28.6 µs ± 2.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.4 µs ± 979 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            31.5 µs ± 4.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            148 µs ± 7.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

String length: 65536
  regex (compiled): 173 ns ± 3.95 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 613 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 515 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.2 µs ± 796 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.5 µs ± 377 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 4294967296
  regex (compiled): 165 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.9 µs ± 144 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 571 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.1 µs ± 472 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            28.1 µs ± 1.69 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            137 µs ± 6.53 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

1
ทำไมคุณถึงคิดว่าดัชนีไม่ปลอดภัย
James

3
s.index(c)ยก ValueError เมื่อไม่ได้อยู่ในc sดังนั้นฉันคิดว่าปลอดภัยเมื่อฉันแน่ใจว่าสตริงที่จะแบ่งพาร์ติชันมีตัวคั่นไม่ปลอดภัยเป็นอย่างอื่น
Aristide

1
สำหรับดัชนี c อยู่ในหน่วย s ดังนั้นจึงไม่ปลอดภัยและยังเร็วที่สุด
arntg

4

พาร์ติชัน ()อาจดีกว่าแล้วแยก () เพื่อจุดประสงค์นี้เนื่องจากมีผลลัพธ์ที่คาดเดาได้ดีกว่าสำหรับสถานการณ์ที่คุณไม่มีตัวคั่นหรือตัวคั่นมากกว่า


1
ทั้งสองอย่างpartitionและsplitจะทำงานอย่างโปร่งใสกับสตริงว่างหรือไม่มีตัวคั่น เป็นที่น่าสังเกตว่าword[:word.index(':')]จะเกิดขึ้นในทั้งสองกรณีนี้
Rob Hall
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.