[python] 특정 부분 문자열 다음에 문자열을 얻는 방법?

특정 부분 문자열 다음에 문자열을 어떻게 얻을 수 있습니까?

예를 들어, 다음 "world"에 문자열을 가져오고 싶습니다 .my_string="hello python world , i'm a beginner "



답변

가장 쉬운 방법은 아마도 목표 단어를 나누는 것입니다.

my_string="hello python world , i'm a beginner "
print my_string.split("world",1)[1] 

split은 단어 (또는 문자)를 분리하고 선택적으로 분할 수를 제한합니다.

이 예에서는 “world”로 분할하여 하나의 분할로만 제한합니다.


답변

s1 = "hello python world , i'm a beginner "
s2 = "world"

print s1[s1.index(s2) + len(s2):]

어디 사건을 처리하려는 경우 s2입니다 하지 에 존재 s1하고 사용 s1.find(s2)에 반대 index. 해당 호출의 반환 값이 -1인 경우 s2에 없습니다 s1.


답변

아무도 언급하지 않은 것에 놀랐습니다 partition.

def substring_after(s, delim):
    return s.partition(delim)[2]

IMHO,이 솔루션은 @arshajii보다 더 읽기 쉽습니다. 그 외에는 @arshajii가 가장 빠른 것이 가장 좋다고 생각합니다. 불필요한 사본 / 하위 문자열을 만들지 않습니다.


답변

사용하고 싶습니다 str.partition():

>>> my_string.partition("world")[2]
" , i'm a beginner "

이 옵션은 다른 것보다 빠르기 때문 입니다.

구분자가없는 경우 빈 문자열이 생성됩니다.

>>> my_string.partition("Monty")[2]  # delimiter missing
''

원래 문자열을 원하면 반환 된 두 번째str.partition()이 비어 있지 않은지 테스트하십시오 .

prefix, success, result = my_string.partition(delimiter)
if not success: result = prefix

str.split()1로 제한하여 사용할 수도 있습니다 .

>>> my_string.split("world", 1)[-1]
" , i'm a beginner "
>>> my_string.split("Monty", 1)[-1]  # delimiter missing
"hello python world , i'm a beginner "

그러나이 옵션은 느립니다 . 최상의 시나리오의 경우 다음 과 비교할 때 str.partition()15 % 더 빠릅니다str.split() .

                                missing        first         lower         upper          last
      str.partition(...)[2]:  [3.745 usec]  [0.434 usec]  [1.533 usec]  <3.543 usec>  [4.075 usec]
str.partition(...) and test:   3.793 usec    0.445 usec    1.597 usec    3.208 usec    4.170 usec
      str.split(..., 1)[-1]:  <3.817 usec>  <0.518 usec>  <1.632 usec>  [3.191 usec]  <4.173 usec>
            % best vs worst:         1.9%         16.2%          6.1%          9.9%          2.3%

여기에는 구분 기호가 없거나 (최악의 시나리오), 첫 번째 (최고의 시나리오) 또는 아래쪽, 위쪽 또는 마지막 위치에 입력이있는 실행 당 타이밍이 표시 됩니다. 가장 빠른 시간이 표시되어 [...]<...>마크 최악.

위의 표는 아래에서 생성 된 세 가지 옵션 모두에 대한 포괄적 인 타임 트라이얼에 의해 생성됩니다. 2.9GHz Intel Core i7 및 16GB 램이 장착 된 2017 년 모델 15 인치 Macbook Pro에서 Python 3.7.4에서 테스트를 실행했습니다.

이 스크립트는 무작위로 선택된 구분 기호가 있거나없는 임의의 문장을 생성하며, 존재하는 경우 생성 된 문장의 다른 위치에서 반복적으로 무작위 순서로 테스트를 실행합니다 (테스트 중에 발생하는 임의의 OS 이벤트를 고려한 가장 공정한 결과 생성). 그런 다음 결과 표를 인쇄합니다.

import random
from itertools import product
from operator import itemgetter
from pathlib import Path
from timeit import Timer

setup = "from __main__ import sentence as s, delimiter as d"
tests = {
    "str.partition(...)[2]": "r = s.partition(d)[2]",
    "str.partition(...) and test": (
        "prefix, success, result = s.partition(d)\n"
        "if not success: result = prefix"
    ),
    "str.split(..., 1)[-1]": "r = s.split(d, 1)[-1]",
}

placement = "missing first lower upper last".split()
delimiter_count = 3

wordfile = Path("/usr/dict/words")  # Linux
if not wordfile.exists():
    # macos
    wordfile = Path("/usr/share/dict/words")
words = [w.strip() for w in wordfile.open()]

def gen_sentence(delimiter, where="missing", l=1000):
    """Generate a random sentence of length l

    The delimiter is incorporated according to the value of where:

    "missing": no delimiter
    "first":   delimiter is the first word
    "lower":   delimiter is present in the first half
    "upper":   delimiter is present in the second half
    "last":    delimiter is the last word

    """
    possible = [w for w in words if delimiter not in w]
    sentence = random.choices(possible, k=l)
    half = l // 2
    if where == "first":
        # best case, at the start
        sentence[0] = delimiter
    elif where == "lower":
        # lower half
        sentence[random.randrange(1, half)] = delimiter
    elif where == "upper":
        sentence[random.randrange(half, l)] = delimiter
    elif where == "last":
        sentence[-1] = delimiter
    # else: worst case, no delimiter

    return " ".join(sentence)

delimiters = random.choices(words, k=delimiter_count)
timings = {}
sentences = [
    # where, delimiter, sentence
    (w, d, gen_sentence(d, w)) for d, w in product(delimiters, placement)
]
test_mix = [
    # label, test, where, delimiter sentence
    (*t, *s) for t, s in product(tests.items(), sentences)
]
random.shuffle(test_mix)

for i, (label, test, where, delimiter, sentence) in enumerate(test_mix, 1):
    print(f"\rRunning timed tests, {i:2d}/{len(test_mix)}", end="")
    t = Timer(test, setup)
    number, _ = t.autorange()
    results = t.repeat(5, number)
    # best time for this specific random sentence and placement
    timings.setdefault(
        label, {}
    ).setdefault(
        where, []
    ).append(min(dt / number for dt in results))

print()

scales = [(1.0, 'sec'), (0.001, 'msec'), (1e-06, 'usec'), (1e-09, 'nsec')]
width = max(map(len, timings))
rows = []
bestrow = dict.fromkeys(placement, (float("inf"), None))
worstrow = dict.fromkeys(placement, (float("-inf"), None))

for row, label in enumerate(tests):
    columns = []
    worst = float("-inf")
    for p in placement:
        timing = min(timings[label][p])
        if timing < bestrow[p][0]:
            bestrow[p] = (timing, row)
        if timing > worstrow[p][0]:
            worstrow[p] = (timing, row)
        worst = max(timing, worst)
        columns.append(timing)

    scale, unit = next((s, u) for s, u in scales if worst >= s)
    rows.append(
        [f"{label:>{width}}:", *(f" {c / scale:.3f} {unit} " for c in columns)]
    )

colwidth = max(len(c) for r in rows for c in r[1:])
print(' ' * (width + 1), *(p.center(colwidth) for p in placement), sep="  ")
for r, row in enumerate(rows):
    for c, p in enumerate(placement, 1):
        if bestrow[p][1] == r:
            row[c] = f"[{row[c][1:-1]}]"
        elif worstrow[p][1] == r:
            row[c] = f"<{row[c][1:-1]}>"
    print(*row, sep="  ")

percentages = []
for p in placement:
    best, worst = bestrow[p][0], worstrow[p][0]
    ratio = ((worst - best) / worst)
    percentages.append(f"{ratio:{colwidth - 1}.1%} ")

print("% best vs worst:".rjust(width + 1), *percentages, sep="  ")


답변

정규 표현식을 사용 하여이 작업을 수행하려면 캡처하지 않는 그룹을 사용하여 “world”라는 단어를 얻은 다음 모든 것을 잡을 수 있습니다.

(?:world).*

예제 문자열은 여기에서 테스트 됩니다


답변

“substring”이라는이 패키지를 사용할 수 있습니다. “pip install substring”을 입력하십시오. 시작 및 끝 문자 / 표시를 언급하여 부분 문자열을 얻을 수 있습니다.

예를 들면 다음과 같습니다.

import substring

s = substring.substringByChar("abcdefghijklmnop", startChar="d", endChar="n")

print(s)

산출:

s = defghijklmn


답변

그것은 오래된 질문이지만 매우 똑같은 시나리오에 직면했습니다. 나는 “낮은”이라는 단어를 데미 리터로 사용하여 문자열을 나눌 필요가 있습니다. 문제는 저와 같은 문자열에 같은 단어가 있다는 것입니다.

이 방법으로 re 모듈을 사용하여 해결했습니다.

import re

string = '...below...as higher prices mean lower demand to be expected. Generally, a high reading is seen as negative (or bearish), while a low reading is seen as positive (or bullish) for the Korean Won.'

정확한 단어와 일치시키기 위해 정규 표현식과 함께 re.split을 사용하십시오.

stringafterword = re.split('\\blow\\b',string)[-1]
print(stringafterword)
' reading is seen as positive (or bullish) for the Korean Won.'

일반적인 코드는 다음과 같습니다.

re.split('\\bTHE_WORD_YOU_WANT\\b',string)[-1]

이것이 누군가를 도울 수 있기를 바랍니다!