Programing

한 줄로 여러 칸을 간단하게 제거할 수 있는 방법이 있는가?

c10106 2022. 4. 9. 10:07
반응형

한 줄로 여러 칸을 간단하게 제거할 수 있는 방법이 있는가?

다음 문자열을 가정하십시오.

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'

foo문자열:

" ".join(foo.split())

이렇게 하면 "모든 공백 문자(공간, 탭, 줄, 리턴, 폼피드)"가 제거되지만 주의하십시오(hhhsaffar 덕택, 주석 참조).즉,"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)

사용자 마틴 토마(Martin Thoma)가 코멘트에서 언급한 바와 같이, 쉼표 앞의 공간이 PEP 8에 펫 소변으로 나열되어 있기 때문이다.

regexes를 "\s"와 함께 사용하고 간단한 문자열.split(')을 수행하면 새로운 선, 캐리지 리턴, 탭과 같은 다른 공백도 제거된다.이것이 원하지 않는 한, 여러 개공간만 하기 위해, 나는 이러한 예들을 제시한다.

11개 단락, 1000단어, 6665바이트의 로렘 입숨을 사용해 현실적인 시간 테스트를 했고, 다음 기간 내내 임의 길이의 여분의 공간을 사용했다.

original_string = ''.join(word + (' ' * random.randint(1, 10)) for word in lorem_ipsum.split(' '))

원라이너는 기본적으로 선행/트레이닝 공간을 분리하고 선행/트레이닝 공간을 보존한다(단, ONE ;-).

# 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생각에 "버전"은 첫 번째 실행에서 한 번 수정되면 연속 실행이 빨라질 것으로 예상되므로 복사본을 만들었다. 이것이 시간을 더하는 것처럼 나는 이 끈 카피를 다른 두 개에 더해서 시대가 논리적으로만 차이를 보이도록 했다.인스턴스에서의 메인 실행은 단 한 번만 실행된다는 것을 명심하라; 내가 이 일을 한 원래 방식인,while루프는 같은 라벨에 붙어서 작동했고original_string그래서 2차 주행은 할 일이 없을 것이다.함수를 호출하고 두 개의 다른 레이블을 사용하는 지금 설정 방식은 문제가 되지 않는다.덧붙여 말했다.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

하찮은 끈의 경우, 그 다음으로는 중루프가 가장 빠른 것 같고, 그 다음으로는 피토닉 스트링 스플릿/조인, 그리고 뒤쪽을 잡아당기는 레그스가 있을 것 같다.

비종교적 문자열의 경우 고려해야 할 사항이 좀 더 있는 것 같다. 32비트 2.7?- 구조하러 간다! - 2.7 64비트?awhile32비트 3.2, "속성"과 함께 사용join. 64비트 3.3, 시작:while반복한다. 다시.

결국, 필요에 따라/어디서/어디서나 성능을 향상시킬 수 있지만, 맨트라를 항상 기억하는 것이 가장 좋다.

  1. 작동하게 만드세요.
  2. 옳게 하세요.
  3. 빨리 하세요.

이안알, YMMV, 동굴 비버!

나는 폴 맥과이어의 의견에 동의해야 한다.나에게.

' '.join(the_string.split())

레그스를 채찍질하는 것보다 훨씬 더 낫다.

나의 측정치(리눅스와 파이썬 2.5)는 스플릿-그 후 조인 속도가 "re.sub(...)"보다 거의 5배 빠르다는 것을 보여주며, 그래도 한 번 regex를 사전 컴파일하고 여러 번 연산을 하면 세 배나 빠르다.그리고 그것은 어느 모로 보나 이해하기 쉽다. 훨씬 더 피토닉적이다.

이전 솔루션과 유사하지만 좀 더 구체적인: 두 개 이상의 공간을 하나 이상의 공간으로 대체:

>>> import re
>>> s = "The   fox jumped   over    the log."
>>> re.sub('\s{2,}', ' ', s)
'The fox jumped over the log.'

소박한 영혼

>>> import re
>>> s="The   fox jumped   over    the log."
>>> print re.sub('\s+',' ', s)
The fox jumped over the log.

나는 다음과 같은 방법을 시도해 보았고 그것은 심지어 다음과 같은 극단적인 경우에서도 통한다.

str1='          I   live    on    earth           '

' '.join(str1.split())

그러나 정규 표현을 선호하면 다음과 같이 할 수 있다.

re.sub('\s+', ' ', str1)

비록 후행과 종료 공간을 제거하기 위해서는 약간의 사전 처리를 해야 한다.

또한 .apply(..)를 사용할 필요 없이 Panda DataFrame에서 문자열 분할 기법을 사용할 수 있는데, 이 기법은 많은 수의 문자열에서 신속하게 작업을 수행해야 할 경우에 유용하다.여기 한 줄에 있다.

df['message'] = (df['message'].str.split()).str.join(' ')

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

import re
string = re.sub('[ \t\n]+', ' ', 'The     quick brown                \n\n             \t        fox')

이렇게 하면 모든 탭, 새 선 및 단일 공백이 있는 다중 화이트 스페이스가 제거된다.

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='') 

결과: 코드로서

"Remove all space:Youcanselectbelowtrimsforremovingwhitespace!!BRAliakbar"
"Remove leading space:You can select below trims for removing white space!!   BR Aliakbar"     
"Remove trailing spaces: You can select below trims for removing white space!!   BR Aliakbar"
"Remove leading and trailing spaces:You can select below trims for removing white space!!   BR Aliakbar"
"Remove more than one space: You can select below trims for removing white space!! BR Aliakbar" 

문장의 앞, 뒤 및 안에 있는 모든 여분의 공백을 제거하는 코드 한 줄:

sentence = "  The   fox jumped   over    the log.  "
sentence = ' '.join(filter(None,sentence.split(' ')))

설명:

  1. 전체 문자열을 목록으로 분할하십시오.
  2. 목록에서 빈 요소를 필터링하십시오.
  3. 단일 공백으로 나머지 요소 다시 가입*

*남은 요소는 구두점이 있는 단어 또는 단어 등이어야 한다.나는 이것을 광범위하게 테스트하지 않았지만, 이것은 좋은 출발점이 될 것이다.잘했어!

" ".join(foo.split())하나의 선행 및/또는 후행 공백을 완전히 제거하기 때문에 질문한 질문에 대해서는 정확하지 않다.따라서, 만약 그것들이 또한 1백으로 대체된다면, 당신은 다음과 같은 일을 해야 한다.

" ".join(('*' + foo + '*').split()) [1:-1]

물론 덜 우아하다.

어떤 경우에는 모든 공백 문자의 연속적인 발생을 해당 문자의 단일 인스턴스로 대체하는 것이 바람직하다.그렇게 하기 위해서 당신은 역참조하는 규칙적인 표현을 사용할 것이다.

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

사용자 생성 문자열을 가장 빨리 얻을 수 있는 방법은 다음과 같다.

if '  ' in text:
    while '  ' in text:
        text = text.replace('  ', ' ')

서킷이 짧으면 비단뱀붙이의 포괄적인 대답보다 약간 빠를 수 있다.효율을 추구하고 단일 공간 다양성의 여분의 화이트스페이스를 철저히 제거하고자 하는 경우 이 작업을 수행하십시오.

왜냐하면 여기서 질문한 @pythonlarry는 누락된 발전기 기반 버전이기 때문이다.

단체 가입은 쉽다.그룹비는 같은 키로 요소들을 연속적으로 그룹화한다.그리고 각 그룹의 키 쌍과 요소 리스트를 반환한다.그래서 열쇠가 공간일 때 공간은 다른 그룹 전체로 돌아온다.

from itertools import groupby
def group_join(string):
  return ''.join(' ' if chr==' ' else ''.join(times) for chr,times in groupby(string))

변종별 그룹은 단순하지만 매우 느리다.이제 발전기 변형에 대해 알아보자.여기서 우리는 반복기, 끈을 소비하고, 한 자에 따르는 차자를 제외한 모든 차자를 생산한다.

def generator_join_generator(string):
  last=False
  for c in string:
    if c==' ':
      if not last:
        last=True
        yield ' '
    else:
      last=False
    yield c

def generator_join(string):
  return ''.join(generator_join_generator(string))

그래서 나는 다른 전설의 입숨으로 타이밍을 맞추었다.

  • while_message 0.015868543065153062
  • re_message 0.22579886706080288
  • etright_messages 0.40058281796518713
  • group_migrate 5.53206754301209
  • generator_reason 1.6673167790286243

Hello와 World를 64KB의 공간으로 구분

  • 한편_1902년 2.99308711003512
  • re_message 0.08232860406860709
  • netify_messages 6.294375243945979
  • group_model 2.4320066600339487
  • generator_instant 6.329648651066236

원문을 잊지 말라.

  • while_messages 0.002160938922315836
  • re_message 0.008620491018518806
  • netified_messages 0.0056500009956361
  • group_19028368217987008393
  • generator_reason 0.009435956948436797

여기서 거의 우주에 가까운 문자열 그룹 조인에서 흥미로운 점은 타이밍이 항상 중앙분리대를 나타낸다는 것이다.

꽤 놀랍다 - 어느 누구도 다른 모든 게시물보다 훨씬 빠른 간단한 기능을 게시하지 않았다.자, 시작한다:

def compactSpaces(s):
    os = ""
    for c in s:
        if c != " " or (os and os[-1] != " "):
            os += c 
    return os
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())
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])

맨 처음 것, 제1; 전자or 두 의2의 인인드를 .or백색 공간을 이끄는 문자열의 시작을 다루고, 마지막은 후행의 백색 공간을 다룬다.

사용 증빙을 위해 이 링크는 당신에게 테스트를 제공할 것이다.

https://regex101.com/r/meBYli/4

re.split 기능과 함께 사용한다.

나는 다른 예들을 많이 읽어보지는 않았지만, 나는 단지 여러 개의 연속된 공간 문자를 통합하기 위해 이 방법을 만들었다.

어떤 라이브러리도 사용하지 않으며, 대본 길이 면에서는 비교적 길지만, 복잡한 구현은 아니다.

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

이렇게 하면 된다. :)

# python... 3.x
import operator
...
# line: line of text
return " ".join(filter(lambda a: operator.is_not(a, ""), line.strip().split(" ")))

참조URL: https://stackoverflow.com/questions/1546226/is-there-a-simple-way-to-remove-multiple-spaces-in-a-string

반응형