a 전에 모든 것을 얻는 방법 : in a string Python


106

나는 : 앞에 문자열의 모든 문자를 얻는 방법을 찾고 있지만 어디서 시작 해야할지 모르겠습니다. 정규식을 사용합니까? 그렇다면 어떻게?

string = "Username: How are you today?"

누군가 내가 할 수있는 일에 대한 예를 보여줄 수 있습니까?

답변:


177

split기능을 사용하십시오 . 목록을 반환하므로 첫 번째 요소를 유지할 수 있습니다.

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

12
어느 제한 분할을하거나,이 경우 - 사용s1.partition(':')[0]
존 클레멘트

매우 유용하고 유익했습니다. 게다가 그것은 큰 도움 감사합니다!
0Cool

2
모든 ':'를 처리하고 전체 배열을 생성하므로 긴 문자열에는 적합하지 않으므로 split을 사용하지 마십시오. 색인을 사용하는 @Hackaholic의 접근 방식을 참조하세요. 그 하나는 분명히 효과적이지 않은 정규식을 권장합니다. 또한 인덱스 기반 인 .substringBefore ()의 표준 작업을 수행하려면 파이썬 옵션이 있어야합니다. 또한 편의를 위해 .substringBeforeLast () 등과 같은 변형이 있어야합니다 (코드를 반복해서는 안 됨). 파티션에 대한 요점을 발견했습니다-예, ':'이후 처리가 적지 만 여전히 '1'이 아닌 <class 'tuple'> : ( '1', ':', '2 : 3')을 반환합니다.
arntg

47

사용 index:

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

인덱스는 :문자열 의 위치를 ​​제공 한 다음 슬라이스 할 수 있습니다.

정규식을 사용하려는 경우 :

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

match 문자열의 시작부터 일치합니다.

당신은 또한 사용할 수 있습니다 itertools.takewhile

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

3
이 메서드 (string [: string.index ( ":")])는 분할보다 더
Damien

속도를 위해 정규식을 사용하지 마십시오. 여기에 언급 된 첫 번째 인덱스 옵션을 사용하십시오. Regex는 분명히 효과적이지 않습니다. 또한 인덱스 기반 인 .substringBefore ()의 표준 작업을 수행하려면 파이썬 옵션이 있어야합니다. 또한 편의를 위해 .substringBeforeLast () 등과 같은 변형이 있어야합니다 (코드를 반복해서는 안 됨). 이 답변을 업데이트하여 인덱스가 더 잘 작동하는 이유와 fredtantini의 응답에서 더 높은 투표를 포함하여 다른 접근 방식에 대해 왜 사용해야하는지 설명하도록 제안하십시오.
arntg

존재하지 않으면 색인이 실패합니다.
Marc

19

regex이건 필요 없어

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

split방법을 사용 하여 ':'문자 에서 문자열을 분할 할 수 있습니다.

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

그리고 요소 [0]를 잘라서 문자열의 첫 번째 부분을 얻습니다.

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

8

나는 Python 3.7.0 (IPython)에서 이러한 다양한 기술을 벤치마킹했습니다.

TLDR

  • 가장 빠름 (분할 기호 c가 알려진 경우) : 미리 컴파일 된 정규식.
  • 가장 빠름 (그렇지 않은 경우) : s.partition(c)[0].
  • 안전 (예 :에 c없을 수있는 경우 s) : 파티션, 분할.
  • 안전하지 않음 : 색인, 정규식.

암호

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)c가에 있지 않을 때 ValueError를 발생 s시킵니다. 따라서 분할 할 문자열에 구분 기호가 포함되어 있다고 확신 할 때 안전하다고 생각하고 그렇지 않으면 안전하지 않습니다.
Aristide

1
인덱스의 경우 c는 s에 있으므로 안전하지 않고 여전히 가장 빠릅니다.
arntg

2

이 목적을 위해 partition () 이 split ()보다 나을 수 있습니다. 구분 기호가 없거나 더 많은 구분 기호가없는 상황에 대해 더 나은 예측 가능한 결과를 제공하기 때문입니다.


1
partition및 둘 다 split빈 문자열 또는 구분 기호없이 투명하게 작동합니다. 이 word[:word.index(':')]두 경우 모두에서 튀어 나올 것이라는 점은 주목할 가치가 있습니다.
Rob Hall
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.