% s를 {0}, {1} (으)로 바꾸는 방법…


11

나중에 대체 할 자리 표시자를 포함하는 문자열을 가져와야합니다.

"A %s B %s"

그리고 그것을 다음으로 바꾸십시오 :

"A {0} B {1}"

나는 생각해 냈다 :

def _fix_substitution_parms(raw_message):
  rv = raw_message
  counter = 0
  while '%s' in rv:
    rv = rv.replace('%s', '{' + str(counter) + '}', 1)
    counter = counter + 1
return rv

그것은 효과가 있지만, "아이디 오 매틱"파이썬이 아니라, 매우 어색한 느낌이 든다.

관용적 인 파이썬 솔루션은 어떻습니까?

설명을위한 업데이트 :

  • 결과 문자열은 파이썬 내에서 사용되지 않습니다. 내가 어떻게 거기에 카운터 번호가 필요합니다! (그래서{} 충분하지 않습니다)!
  • 난 단지에 대해 신경 쓸 필요가 %s메시지 만 사용 보장으로, 문자열 %s(NO %i %f무엇이든지)

"re.sub"는 번호가있는 중괄호로 동적으로 대체하기위한 대체 기능을 수행 할 수 있습니다. 그건 그렇고 : 숫자없이 {}로 바꾸면 효과가 있습니다.
Michael Butscher

3
작동하는 솔루션이 있고 개선하고 싶을 경우 codereview.stackexchange.com
kojiro

@kojiro "너무
어리 석다

답변:


5

나는 Reznik이 원래 제안한 것을 수행하고 다음과 같이 요구 .format합니다.

def _fix_substitution_parms(raw_message: str) -> str:
    num_to_replace = raw_message.count("%s")
    python_format_string_message = raw_message.replace("%s", "{{{}}}")
    final_message = python_format_string_message.format(*range(num_to_replace))
    return final_message

%s텍스트에 2 가있는 경우에만 작동 합니까?
Charif DZ

@CharifDZ와 Aran-Fey-편집을 참조하십시오. 당신은 미리 손을 세어
Dan

좋은 타협처럼 보입니다 ... 읽기 쉽지만 너무 화려하지는 않습니다.
GhostCat 인사말 Monica C.

8

re.sub람다 함수와 함께 사용 하여 각 요소에 대해 대체를 한 번 다시 적용하고 itertools.count숫자를 순차적으로 가져 옵니다 .

import itertools
import re

s = "A %s B %s"

counter = itertools.count()
result = re.sub('%s', lambda x: f'{{{next(counter)}}}', s)
print(result)  # 'A {0} B {1}'

새로 고쳐야하므로이 작업을 한 번 이상 수행하려면이 기능을 랩핑해야합니다 itertools.count.


니스, 내가 찾을이기는하지만 그것은 조금 "애매한";-)
GhostCat 경례 모니카 C.

@GhostCat 그것은 모호하지 않습니다, 당신 next(counter)이 다음 값을 생산 한다고 부르면 카운터는 발전기입니다 . 나는 항상이 발전기에 대해 정말 좋은 대답을 잊었습니다.
Charif DZ

@GhostCat 정규식과 같은 줄의 함수형 프로그래밍 : -PI "불분명"은 이러한 도구에 얼마나 많이 사용되는지에 달려 있습니다.
jfaccioni

3

나는 그 shoudl 작품 생각

rv.replace('%s','{{{}}}').format(*range(rv.count('%s')))


1
@GhostCat은 한 명의 라이너에게 유혹을받지 않습니다. 사람들은 코드를 유지해야한다는 것을 기억하십시오
Dan

1
@ 댄. 그러나 코드가 적을수록 유지해야 할 코드가 적습니다.
GhostCat 인사말 Monica C.

그럼에도 불구하고 디버깅하기가 어렵고 미래의 개발자가 읽기가 더 어렵습니다. 이 답변은 내 것과 거의 비슷하며 동일한 함수 호출 (스왑 및 결합을위한 교체 교체)이 있지만 중간 단계에 문제가 있으면 어떻게해야합니까? 어떻게 격리하겠습니까? 그리고 코드에서 수행하는 작업을 이해하는 데 새로운 개발자가 더 빠릅니다. 이 많은 논리를 한 줄에 넣지 않는 것이 좋습니다.
Dan

1
좋은 라이너는 아닙니다. X.join(Y.split(Z))복잡한 작성 방법이며 호출 Y.replace(X, Z)을 마무리 할 필요가 없습니다 . rangelist(...)
Aran-Fey

1
@ 댄 예, 그것에 대해 죄송합니다 (지금 한 줄에만) :)
Reznik

1

하여 re.sub동적 교체를 위해 :

import re

text = "A %s B %s %s B %s"


def _fix_substitution_parms(raw_message):
    counter = 0
    def replace(_):
        nonlocal counter
        counter += 1
        return '{{{}}}'.format(counter - 1)
    return re.sub('%s', replace, raw_message)


print(_fix_substitution_parms(text))  # A {0} B {1} {2} B {3}

1
이것은 이스케이프 된 자리 표시 자 ( %%s)를 설명하지 않습니다 . 우려되는 경우 정규 표현식을 r'(?<!%)%s'대신 사용할 수 있습니다 .
Aran-Fey

당신이 바보 같은 질문을 허용한다면 : {{{}}}실제로 무엇에 관한 것입니까?
GhostCat 경례 모니카 C.

탈출하기위한 문자열 형식화 {우리는 \{평소처럼 하지 않습니다 {{.
Charif DZ

1

발전기 사용하기 :

def split_and_insert(mystring):
    parts = iter(mystring.split('%s'))
    yield next(parts)
    for n, part in enumerate(parts):
        yield f'{{{n}}}'
        yield part

new_string = ''.join(split_and_insert("A %s B %s"))

-4

.format을 사용해 보셨습니까?

string.format (0 = 값, 1 = 값)

그래서:

"A {0} B {1}".format(0=value, 1=value)


1
이 도움말 사람이 어떻게 설정 않습니다 %s{}?
Aran-Fey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.