IT

특정 부분 문자열 다음에 문자열 얻기

lottoking 2020. 5. 21. 08:19
반응형

특정 부분 문자열 다음에 문자열 얻기


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

예를 들어 "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 's가 가장 빠르다는 것이 최선이라고 생각합니다. 불필요한 사본 / 하위 문자열을 만들지 않습니다.


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

(?:world).*

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


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

이 방법으로 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]

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


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

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

import substring

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

print(s)

산출:

s = defghijklmn


사용하고 싶습니다 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%

This shows timings per execution with inputs here the delimiter is either missing (worst-case scenario), placed first (best case scenario), or in the lower half, upper half or last position. The fastest time is marked with [...] and <...> marks the worst.

The above table is produced by a comprehensive time trial for all three options, produced below. I ran the tests on Python 3.7.4 on a 2017 model 15" Macbook Pro with 2.9 GHz Intel Core i7 and 16 GB ram.

This script generates random sentences with and without the randomly selected delimiter present, and if present, at different positions in the generated sentence, runs the tests in random order with repeats (producing the fairest results accounting for random OS events taking place during testing), and then prints a table of the results:

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

참고URL : https://stackoverflow.com/questions/12572362/get-a-string-after-a-specific-substring

반응형