이 문자열을 가정하십시오.
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 로, 사용자가 언급 한 마틴 토마스 코멘트에.
r"\s\s+"
이미 단일 공간을 대체하지 않도록 정규 표현식을 변경하는 경향이 있습니다 .
"\s{2,}"
중간 정도의 정규식 동작을 모르는 해결 방법이 아닌 이유 는 무엇입니까?
s
새 값을 반환합니다.
\s+
행이 " 하나 이상의 공백을 공백으로 바꾸기"라고 읽습니다 . 전자는 즉시 멈추고 "한 공간을 한 공간으로 대체하는 이유는 무엇입니까?" 나에게 그것은 (매우 작은) 코드 냄새입니다. 사실은 어쨌든 새로운 문자열로 복사 할 것 같은, 둘 사이에 전혀 성능의 차이가있을 수 기대하지 않을 것이다,에 관계없이 공간이 복사되는 위치의 정지 및 테스트가 에서 .
\s\s+
이것은 TAB 문자를 다시 일반 공간으로 정규화하지 않기 때문에 권장 하지 않습니다. SPACE + TAB은 이런 식으로 대체됩니다.
"\ s"와 함께 정규 표현식을 사용하고 간단한 string.split ()을 사용하면 줄 바꿈, 캐리지 리턴, 탭과 같은 다른 공백 도 제거 됩니다 . 이것이 바람직하지 않으면, 여러 공간 만 수행 하기 위해이 예제를 제시합니다.
나는 11 개의 문단, 1000 단어, 6665 바이트의 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
참고 : " main while
버전"은 original_string
첫 번째 실행에서 일단 수정되면 연속 실행이 더 빠를 것이라고 생각합니다. 시간이 추가됨에 따라이 문자열 복사본을 다른 두 개에 추가하여 시간에 논리의 차이 만 표시했습니다. stmt
on 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 루프가 가장 빠르고 파이썬 문자열 스플릿 / 조인이 있고 정규 표현식이 뒤쪽을 당기는 것처럼 보입니다.
사소한 문자열 의 경우 고려해야 할 것이 더 있습니다. 32 비트 2.7? 구조에 대한 정규식입니다! 2.7 64 비트? while
루프는 상당한 차이로, 최고입니다. 32 비트 3.2는 "proper"와 함께 사용하십시오 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())
정규식을 꺼내는 것보다 훨씬 좋습니다.
내 측정 (Linux 및 Python 2.5)은 split-then-join이 "re.sub (...)"를 수행하는 것보다 거의 5 배 빠르며 정규 표현식을 한 번 사전 컴파일하고 작업을 수행하면 여전히 3 배 빠름을 보여줍니다 여러 번. 그리고 그것은 훨씬 더 이해하기 쉽습니다- 훨씬 더 파이썬적인 것입니다.
경우에 따라 모든 공백 문자의 연속 발생을 단일 인스턴스로 바꾸는 것이 바람직 합니다. 문자 . 역 참조가있는 정규식을 사용하면됩니다.
(\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'
한 줄의 코드로 문장 앞, 뒤 및 문장 내의 모든 추가 공백을 제거합니다.
sentence = " The fox jumped over the log. "
sentence = ' '.join(filter(None,sentence.split(' ')))
설명:
* 나머지 요소는 구두점 등이 포함 된 단어 나 단어 여야합니다. 나는 이것을 광범위하게 테스트하지는 않았지만 좋은 출발점이되어야합니다. 모두 제일 좋다!
파이썬 개발자를위한 솔루션 :
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
사용자 생성 문자열에 가장 빠른 속도는 다음과 같습니다.
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
처리하는 공백 인 경우 None으로 분할 하면 반환 된 값에 빈 문자열이 포함되지 않습니다.
단어 사이의 선행, 후행 및 추가 공백을 고려하여 공백을 제거하려면 다음을 사용하십시오.
(?<=\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
이것은 모든 이중 공간을 단일 공간으로 대체하고 1000 번 수행합니다. 그것은 당신이 2000 개의 추가 공간을 가질 수 있고 여전히 작동한다는 것을 의미합니다. :)
분할하지 않고 간단한 방법이 있습니다.
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='')
결과:
모든 공간 제거 : 공백 제거를 위해 트림을 선택할 수 있습니다 !! Braaikbar 선행 공간 제거 : 공백 제거를 위해 아래 트림을 선택할 수 있습니다 !! 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)))