สมมติว่าสตริงนี้:
The fox jumped over the log.
กลายเป็น:
The fox jumped over the log.
อะไรคือวิธีที่ง่ายที่สุด (1-2 บรรทัด) เพื่อให้ได้สิ่งนี้โดยไม่ต้องแยกและเข้าไปในรายการ?
สมมติว่าสตริงนี้:
The fox jumped over the log.
กลายเป็น:
The fox jumped over the log.
อะไรคือวิธีที่ง่ายที่สุด (1-2 บรรทัด) เพื่อให้ได้สิ่งนี้โดยไม่ต้องแยกและเข้าไปในรายการ?
คำตอบ:
>>> import re
>>> re.sub(' +', ' ', 'The quick brown fox')
'The quick brown fox'
string.split
จัดการช่องว่างทุกชนิด
re.sub(' {2,}', ' ', 'The quick brown fox')
เพื่อป้องกันไม่ให้เปลี่ยนซ้ำซ้อนเดียวกับพื้นที่เดียวพื้นที่
foo
คือสตริงของคุณ:
" ".join(foo.split())
ได้รับการเตือนแม้ว่าสิ่งนี้จะลบ "อักขระช่องว่างทั้งหมด (ช่องว่างแท็บขึ้นบรรทัดใหม่กลับฟอร์มป้อนข้อมูล)" (ขอบคุณhhsaffarดูความคิดเห็น) กล่าวคือมีประสิทธิภาพจะจบลงเช่น"this is \t a test\n"
"this is a test"
import re
s = "The fox jumped over the log."
re.sub("\s\s+" , " ", s)
หรือ
re.sub("\s\s+", " ", s)
เนื่องจากพื้นที่ก่อนจุลภาคจะปรากฏเป็นโกรธสัตว์เลี้ยงในPEP 8เป็นที่กล่าวถึงโดยผู้ใช้มาร์ติน Thomaในการแสดงความคิดเห็น
r"\s\s+"
เพื่อไม่พยายามแทนที่ช่องว่างเดียวแล้ว
"\s{2,}"
แต่หลีกเลี่ยงวิธีแก้ปัญหาโดยไม่ทราบว่าพฤติกรรม Regex ขั้นสูงอยู่ในระดับปานกลาง
s
แต่ส่งคืนค่าใหม่
\s+
จะทำให้บรรทัดอ่าน "แทนที่ช่องว่างหนึ่งช่องขึ้นไปด้วยช่องว่าง" แทนที่จะ "แทนที่ช่องว่างสองช่องขึ้นไปด้วยช่องว่าง" อดีตทำให้ฉันหยุดและคิดว่า "ทำไมแทนที่หนึ่งช่องว่างด้วยช่องว่างเดียว? สำหรับฉันนั่นเป็นกลิ่นรหัส (น้อยมาก) ฉันไม่คาดหวังว่าจะมีความแตกต่างด้านประสิทธิภาพใด ๆ ระหว่างทั้งสองเนื่องจากจะต้องคัดลอกลงในสายอักขระใหม่อยู่แล้วและต้องหยุดและทดสอบโดยไม่คำนึงถึงว่าพื้นที่ถูกคัดลอกมาจากที่ใด
\s\s+
เพราะจะไม่ทำให้อักขระ TAB กลับสู่สภาพปกติ SPACE + TAB จะถูกแทนที่ด้วยวิธีนี้
ใช้ regexes กับ "\ s" และการทำ string.split ง่าย () 's จะยังลบช่องว่างอื่น ๆ ที่ชอบ - บรรทัดใหม่ผลตอบแทนการขนส่งแท็บ เว้นแต่นี้เป็นที่ต้องการที่จะเพียงทำช่องว่างหลายผมนำเสนอตัวอย่างเหล่านี้
ฉันใช้11 ย่อหน้า, 1,000 คำ, 6665 bytes ของ Lorem Ipsumเพื่อรับการทดสอบตามเวลาจริงและใช้ช่องว่างพิเศษที่มีความยาวแบบสุ่มตลอด:
original_string = ''.join(word + (' ' * random.randint(1, 10)) for word in lorem_ipsum.split(' '))
ซับหนึ่งจะทำแถบของช่องว่างนำหน้า / ท้ายใด ๆ และจะรักษาพื้นที่นำหน้า / ท้าย (แต่เพียงหนึ่ง ;-)
# setup = '''
import re
def while_replace(string):
while ' ' in string:
string = string.replace(' ', ' ')
return string
def re_replace(string):
return re.sub(r' {2,}' , ' ', string)
def proper_join(string):
split_string = string.split(' ')
# To account for leading/trailing spaces that would simply be removed
beg = ' ' if not split_string[ 0] else ''
end = ' ' if not split_string[-1] else ''
# versus simply ' '.join(item for item in string.split(' ') if item)
return beg + ' '.join(item for item in split_string if item) + end
original_string = """Lorem ipsum ... no, really, it kept going... malesuada enim feugiat. Integer imperdiet erat."""
assert while_replace(original_string) == re_replace(original_string) == proper_join(original_string)
#'''
# while_replace_test
new_string = original_string[:]
new_string = while_replace(new_string)
assert new_string != original_string
# re_replace_test
new_string = original_string[:]
new_string = re_replace(new_string)
assert new_string != original_string
# proper_join_test
new_string = original_string[:]
new_string = proper_join(new_string)
assert new_string != original_string
หมายเหตุ: " โปรดทราบว่าหลักwhile
เวอร์ชั่น" ทำสำเนาoriginal_string
เพราะฉันเชื่อว่าเมื่อมีการแก้ไขในการรันครั้งแรกการรันต่อเนื่องจะเร็วขึ้น (ถ้าเพียงเล็กน้อย) เนื่องจากนี่เป็นการเพิ่มเวลาฉันจึงเพิ่มการคัดลอกสตริงนี้ไปยังอีกสองรายการเพื่อให้เวลาแสดงความแตกต่างในตรรกะเท่านั้น stmt
ในtimeit
อินสแตนซ์จะถูกดำเนินการเพียงครั้งเดียวเท่านั้น วิธีดั้งเดิมที่ฉันทำคือการwhile
วนซ้ำทำงานบนฉลากเดียวกันoriginal_string
ดังนั้นการวิ่งครั้งที่สองจะไม่มีอะไรทำ วิธีการตั้งค่าในขณะนี้การเรียกใช้ฟังก์ชันโดยใช้สองป้ายกำกับที่แตกต่างกันนั่นไม่ใช่ปัญหา ฉันได้เพิ่มassert
ข้อความไปยังพนักงานทุกคนเพื่อตรวจสอบว่าเราเปลี่ยนแปลงบางอย่างทุกการทำซ้ำ (สำหรับผู้ที่อาจไม่แน่ใจ) เช่นเปลี่ยนเป็นสิ่งนี้และหยุดพัก:
# while_replace_test
new_string = original_string[:]
new_string = while_replace(new_string)
assert new_string != original_string # will break the 2nd iteration
while ' ' in original_string:
original_string = original_string.replace(' ', ' ')
Tests run on a laptop with an i5 processor running Windows 7 (64-bit).
timeit.Timer(stmt = test, setup = setup).repeat(7, 1000)
test_string = 'The fox jumped over\n\t the log.' # trivial
Python 2.7.3, 32-bit, Windows
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.001066 | 0.001260 | 0.001128 | 0.001092
re_replace_test | 0.003074 | 0.003941 | 0.003357 | 0.003349
proper_join_test | 0.002783 | 0.004829 | 0.003554 | 0.003035
Python 2.7.3, 64-bit, Windows
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.001025 | 0.001079 | 0.001052 | 0.001051
re_replace_test | 0.003213 | 0.004512 | 0.003656 | 0.003504
proper_join_test | 0.002760 | 0.006361 | 0.004626 | 0.004600
Python 3.2.3, 32-bit, Windows
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.001350 | 0.002302 | 0.001639 | 0.001357
re_replace_test | 0.006797 | 0.008107 | 0.007319 | 0.007440
proper_join_test | 0.002863 | 0.003356 | 0.003026 | 0.002975
Python 3.3.3, 64-bit, Windows
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.001444 | 0.001490 | 0.001460 | 0.001459
re_replace_test | 0.011771 | 0.012598 | 0.012082 | 0.011910
proper_join_test | 0.003741 | 0.005933 | 0.004341 | 0.004009
test_string = lorem_ipsum
# Thanks to http://www.lipsum.com/
# "Generated 11 paragraphs, 1000 words, 6665 bytes of Lorem Ipsum"
Python 2.7.3, 32-bit
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.342602 | 0.387803 | 0.359319 | 0.356284
re_replace_test | 0.337571 | 0.359821 | 0.348876 | 0.348006
proper_join_test | 0.381654 | 0.395349 | 0.388304 | 0.388193
Python 2.7.3, 64-bit
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.227471 | 0.268340 | 0.240884 | 0.236776
re_replace_test | 0.301516 | 0.325730 | 0.308626 | 0.307852
proper_join_test | 0.358766 | 0.383736 | 0.370958 | 0.371866
Python 3.2.3, 32-bit
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.438480 | 0.463380 | 0.447953 | 0.446646
re_replace_test | 0.463729 | 0.490947 | 0.472496 | 0.468778
proper_join_test | 0.397022 | 0.427817 | 0.406612 | 0.402053
Python 3.3.3, 64-bit
test | minum | maximum | average | median
---------------------+------------+------------+------------+-----------
while_replace_test | 0.284495 | 0.294025 | 0.288735 | 0.289153
re_replace_test | 0.501351 | 0.525673 | 0.511347 | 0.508467
proper_join_test | 0.422011 | 0.448736 | 0.436196 | 0.440318
สำหรับสตริงเล็กน้อยดูเหมือนว่า while-loop จะเร็วที่สุดตามด้วย Pythonic string-split / join และ regex ดึงด้านหลังขึ้นมา
สำหรับสตริงที่ไม่สำคัญดูเหมือนว่าจะต้องพิจารณาอีกเล็กน้อย 32- บิต 2.7 มันเป็น regex เพื่อช่วยเหลือ! 2.7 64-bit? การwhile
วนซ้ำนั้นดีที่สุดโดยมีระยะขอบที่เหมาะสม 32 บิต 3.2 ไปกับ join
"เหมาะสม" 64- บิต 3.3 ไปหาwhile
วง อีกครั้ง
ในท้ายที่สุดเราสามารถปรับปรุงประสิทธิภาพหาก / ที่ไหน / เมื่อต้องการแต่มันเป็นการดีที่สุดที่จะจำมนต์ :
IANAL, YMMV, Caveat Emptor!
' '.join(the_string.split())
เพราะนี่เป็นกรณีการใช้งานปกติ แต่ฉันอยากจะบอกว่าขอบคุณสำหรับการทำงานของคุณ!
' '.join(p for p in s.split(' ') if p)
<- ยังคงสูญเสียพื้นที่รอคอย / ช่องท้าย แต่คิดเป็นหลายช่องว่าง เพื่อให้พวกเขาต้องทำเช่นนั้นparts = s.split(' '); (' ' if not parts[0] else '') + ' '.join(p for p in s.split(' ') if p) + (' ' if not parts[-1] else '')
!
ฉันต้องเห็นด้วยกับความคิดเห็นของ Paul McGuire ถึงฉัน,
' '.join(the_string.split())
เป็นที่นิยมอย่างมากในการตี regex
การวัดของฉัน (Linux และ Python 2.5) แสดงการแบ่งแล้วเข้าร่วมจะเร็วกว่าการทำ "re.sub (... )" เกือบห้าเท่าและยังเร็วกว่าสามเท่าหากคุณทำการคอมไพล์ regex หนึ่งครั้งและทำการดำเนินการ หลายครั้ง. และมันก็เป็นเรื่องที่เข้าใจได้ง่ายขึ้น - มากขึ้น Pythonic
คล้ายกับโซลูชันก่อนหน้า แต่เฉพาะเจาะจงมากขึ้น: แทนที่ช่องว่างสองช่องขึ้นไปด้วยช่องว่างหนึ่งช่อง:
>>> import re
>>> s = "The fox jumped over the log."
>>> re.sub('\s{2,}', ' ', s)
'The fox jumped over the log.'
soultion ง่าย ๆ
>>> import re
>>> s="The fox jumped over the log."
>>> print re.sub('\s+',' ', s)
The fox jumped over the log.
คุณยังสามารถใช้เทคนิคการแยกสตริงใน Pandas DataFrame โดยไม่จำเป็นต้องใช้. apply (.. ) ซึ่งมีประโยชน์หากคุณต้องการดำเนินการอย่างรวดเร็วกับสตริงจำนวนมาก นี่คือหนึ่งบรรทัด:
df['message'] = (df['message'].str.split()).str.join(' ')
import re
string = re.sub('[ \t\n]+', ' ', 'The quick brown \n\n \t fox')
การดำเนินการนี้จะลบแท็บทั้งหมดบรรทัดใหม่และช่องว่างสีขาวหลายช่องด้วยพื้นที่สีขาวเดียว
ฉันได้ลองวิธีการดังต่อไปนี้และยังใช้งานได้กับกรณีที่รุนแรง:
str1=' I live on earth '
' '.join(str1.split())
แต่ถ้าคุณชอบนิพจน์ทั่วไปสามารถทำได้ดังนี้:
re.sub('\s+', ' ', str1)
แม้ว่าการประมวลผลล่วงหน้าบางอย่างจะต้องทำเพื่อที่จะลบพื้นที่ต่อท้ายและจุดสิ้นสุด
ดูเหมือนว่าจะใช้งานได้:
while " " in s:
s = s.replace(" ", " ")
โดยที่ตัวแปรs
แสดงถึงสตริงของคุณ
ในบางกรณีก็เป็นที่พึงปรารถนาเพื่อแทนที่เกิดขึ้นติดต่อกันของตัวละครของช่องว่างทุกท่านด้วยเช่นเดียวของที่ตัวละคร คุณต้องการใช้นิพจน์ทั่วไปที่มีการอ้างอิงย้อนกลับ
(\s)\1{1,}
จับคู่อักขระช่องว่างใด ๆ แล้วตามด้วยอักขระอย่างน้อยหนึ่งรายการ ตอนนี้สิ่งที่คุณต้องทำคือระบุกลุ่มแรก ( \1
) เป็นการแทนที่สำหรับการแข่งขัน
ห่อสิ่งนี้ในฟังก์ชั่น:
import re
def normalize_whitespace(string):
return re.sub(r'(\s)\1{1,}', r'\1', string)
>>> normalize_whitespace('The fox jumped over the log.')
'The fox jumped over the log.'
>>> normalize_whitespace('First line\t\t\t \n\n\nSecond line')
'First line\t \nSecond line'
ทางเลือกอื่น:
>>> import re
>>> str = 'this is a string with multiple spaces and tabs'
>>> str = re.sub('[ \t]+' , ' ', str)
>>> print str
this is a string with multiple spaces and tabs
โค้ดหนึ่งบรรทัดเพื่อลบช่องว่างเพิ่มเติมทั้งหมดก่อนหลังและภายในประโยค:
sentence = " The fox jumped over the log. "
sentence = ' '.join(filter(None,sentence.split(' ')))
คำอธิบาย:
* องค์ประกอบที่เหลือควรเป็นคำหรือคำที่มีเครื่องหมายวรรคตอน ฯลฯ ฉันไม่ได้ทดสอบสิ่งนี้อย่างกว้างขวาง แต่นี่ควรเป็นจุดเริ่มต้นที่ดี ดีที่สุด!
โซลูชันสำหรับนักพัฒนา Python:
import re
text1 = 'Python Exercises Are Challenging Exercises'
print("Original string: ", text1)
print("Without extra spaces: ", re.sub(' +', ' ', text1))
เอาท์พุท:
Original string: Python Exercises Are Challenging Exercises
Without extra spaces: Python Exercises Are Challenging Exercises
def unPretty(S):
# Given a dictionary, JSON, list, float, int, or even a string...
# return a string stripped of CR, LF replaced by space, with multiple spaces reduced to one.
return ' '.join(str(S).replace('\n', ' ').replace('\r', '').split())
เร็วที่สุดที่คุณจะได้รับจากสตริงที่ผู้ใช้สร้างคือ:
if ' ' in text:
while ' ' in text:
text = text.replace(' ', ' ')
ไฟฟ้าลัดวงจรทำให้มันเร็วขึ้นเล็กน้อยกว่าคำตอบที่ครอบคลุม pythonlarry ของ ไปนี้ถ้าคุณหลังจากที่มีประสิทธิภาพและอย่างเคร่งครัดมองหาเพื่อวัชพืชออกจากช่องว่างพิเศษในหลากหลายพื้นที่เดียว
ค่อนข้างแปลกใจ - ไม่มีใครโพสต์ฟังก์ชั่นง่าย ๆ ซึ่งจะเร็วกว่าโซลูชั่นที่โพสต์อื่น ๆ ทั้งหมด นี่มันไป:
def compactSpaces(s):
os = ""
for c in s:
if c != " " or os[-1] != " ":
os += c
return os
หากเป็นช่องว่างที่คุณกำลังดำเนินการอยู่การแยกที่ไม่มีจะไม่มีสตริงว่างในค่าที่ส่งคืน
string = 'This is a string full of spaces and taps'
string = string.split(' ')
while '' in string:
string.remove('')
string = ' '.join(string)
print(string)
ผลลัพธ์ :
นี่คือสตริงที่เต็มไปด้วยช่องว่างและก๊อก
หากต้องการลบพื้นที่สีขาวให้พิจารณานำหน้าต่อท้ายและเพิ่มพื้นที่สีขาวพิเศษระหว่างคำให้ใช้:
(?<=\s) +|^ +(?=\s)| (?= +[\n\0])
or
ข้อตกลงแรกที่มีพื้นที่สีขาวชั้นนำor
ข้อตกลงที่สองกับจุดเริ่มต้นของพื้นที่สีขาวชั้นนำและคนสุดท้ายที่เกี่ยวข้องกับพื้นที่สีขาวต่อท้าย
เพื่อพิสูจน์การใช้งานลิงค์นี้จะให้คุณทดสอบ
https://regex101.com/r/meBYli/4
นี่คือที่จะใช้กับฟังก์ชั่นre.split
ฉันมีวิธีการง่ายๆที่ฉันใช้ในวิทยาลัย
line = "I have a nice day."
end = 1000
while end != 0:
line.replace(" ", " ")
end -= 1
สิ่งนี้จะแทนที่ทุกเว้นวรรคด้วยช่องว่างเดียวและจะทำ 1,000 ครั้ง นั่นหมายความว่าคุณสามารถมีพื้นที่เพิ่มได้ 2,000 พื้นที่และจะยังคงใช้งานได้ :)
ฉันมีวิธีง่าย ๆ โดยไม่แยก:
a = "Lorem Ipsum Darum Diesrum!"
while True:
count = a.find(" ")
if count > 0:
a = a.replace(" ", " ")
count = a.find(" ")
continue
else:
break
print(a)
import re
Text = " You can select below trims for removing white space!! BR Aliakbar "
# trims all white spaces
print('Remove all space:',re.sub(r"\s+", "", Text), sep='')
# trims left space
print('Remove leading space:', re.sub(r"^\s+", "", Text), sep='')
# trims right space
print('Remove trailing spaces:', re.sub(r"\s+$", "", Text), sep='')
# trims both
print('Remove leading and trailing spaces:', re.sub(r"^\s+|\s+$", "", Text), sep='')
# replace more than one white space in the string with one white space
print('Remove more than one space:',re.sub(' +', ' ',Text), sep='')
ผลลัพธ์:
ลบพื้นที่ทั้งหมด: Youcanselectbelowtrimsforremovingwhitespace !! BRAliakbar ลบพื้นที่ชั้นนำ: คุณสามารถเลือกพื้นที่ด้านล่างสำหรับการลบพื้นที่สีขาว !! BR Aliakbar
ลบช่องว่างต่อท้าย: คุณสามารถเลือกด้านล่างภายนอกเพื่อลบพื้นที่สีขาว !! BR Aliakbar ลบช่องว่างนำหน้าและต่อท้าย: คุณสามารถเลือกด้านล่างภายนอกสำหรับการลบพื้นที่สีขาว !! BR Aliakbar ลบมากกว่าหนึ่งช่องว่าง: คุณสามารถเลือกด้านล่างภายนอกเพื่อลบพื้นที่สีขาว !! BR Aliakbar
ฉันไม่ได้อ่านอะไรมากมายในตัวอย่างอื่น ๆ แต่ฉันเพิ่งสร้างวิธีการนี้เพื่อรวมอักขระช่องว่างต่อเนื่องหลายตัว
มันไม่ได้ใช้ไลบรารีใด ๆ และแม้ว่ามันจะค่อนข้างยาวในแง่ของความยาวสคริปต์ แต่ก็ไม่ได้มีการใช้งานที่ซับซ้อน:
def spaceMatcher(command):
"""
Function defined to consolidate multiple whitespace characters in
strings to a single space
"""
# Initiate index to flag if more than one consecutive character
iteration
space_match = 0
space_char = ""
for char in command:
if char == " ":
space_match += 1
space_char += " "
elif (char != " ") & (space_match > 1):
new_command = command.replace(space_char, " ")
space_match = 0
space_char = ""
elif char != " ":
space_match = 0
space_char = ""
return new_command
command = None
command = str(input("Please enter a command ->"))
print(spaceMatcher(command))
print(list(spaceMatcher(command)))