Risposte:
Il modo più semplice è probabilmente quello di dividere la parola target
my_string="hello python world , i'm a beginner "
print my_string.split("world",1)[1]
split prende la parola (o il carattere) su cui dividere e facoltativamente un limite al numero di split.
In questo esempio dividi "mondo" e limitalo a una sola divisione.
target.split('lower',1)[-1].split('low',1)[-1]
my_string.partition("world")[-1]
(o ...[2]
) è più veloce.
s1 = "hello python world , i'm a beginner "
s2 = "world"
print s1[s1.index(s2) + len(s2):]
Se si desidera affrontare il caso in cui nons2
è presente , utilizzare al contrario . Se il valore restituito di quella chiamata è , allora non è in .s1
s1.find(s2)
index
-1
s2
s1
print( s1[s1.index(s2) + len(s2):] is s1[s1.index(s2) + len(s2):])
Sono sorpreso che nessuno abbia menzionato partition
.
def substring_after(s, delim):
return s.partition(delim)[2]
IMHO, questa soluzione è più leggibile di quella di @ arshajii. A parte questo, penso che @ arshajii sia il migliore per essere il più veloce - non crea copie / sottostringhe non necessarie.
str.split(..., 1)
.
Vuoi usare str.partition()
:
>>> my_string.partition("world")[2]
" , i'm a beginner "
perché questa opzione è più veloce delle alternative .
Si noti che questo produce una stringa vuota se manca il delimitatore:
>>> my_string.partition("Monty")[2] # delimiter missing
''
Se desideri avere la stringa originale, verifica se il secondo valore restituito str.partition()
non è vuoto:
prefix, success, result = my_string.partition(delimiter)
if not success: result = prefix
Puoi anche usare str.split()
con un limite di 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 "
Tuttavia, questa opzione è più lenta . Per una migliore dei casi, str.partition()
è facilmente circa il 15% più veloce rispetto a 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%
Questo mostra i tempi per esecuzione con input qui il delimitatore è mancante (scenario peggiore), posizionato per primo (scenario migliore) o nella metà inferiore, metà superiore o ultima posizione. Il tempo più veloce è contrassegnato con [...]
e <...>
segna il peggio.
La tabella sopra è prodotta da una completa cronometro per tutte e tre le opzioni, prodotta di seguito. Ho eseguito i test su Python 3.7.4 su un Macbook Pro 15 "modello 2017 da 2017 con Intel Core i7 da 2,9 GHz e ram da 16 GB.
Questo script genera frasi casuali con e senza il delimitatore selezionato casualmente presente e, se presente, in diverse posizioni nella frase generata, esegue i test in ordine casuale con ripetizioni (producendo i risultati più equi tenendo conto degli eventi casuali del sistema operativo che si verificano durante il test), e quindi stampa una tabella dei risultati:
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=" ")
Se vuoi farlo usando regex, potresti semplicemente usare un gruppo non di acquisizione , per ottenere la parola "mondo" e poi prendere tutto dopo, in questo modo
(?:world).*
La stringa di esempio viene testata qui
result = re.search(r"(?:world)(.*)", "hello python world , i'm a beginner ").group(1)
È possibile utilizzare questo pacchetto chiamato "sottostringa". Basta digitare "pip install substring". È possibile ottenere la sottostringa citando solo i caratteri / indici di inizio e fine.
Per esempio:
import substring
s = substring.substringByChar("abcdefghijklmnop", startChar="d", endChar="n")
print(s)
Produzione:
È una vecchia domanda ma ho affrontato lo stesso scenario, ho bisogno di dividere una stringa usando come demiliter la parola "basso" il problema per me era che ho nella stessa stringa la parola sotto e sotto.
L'ho risolto usando il modulo re in questo modo
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.'
usa re.split con regex per abbinare la parola esatta
stringafterword = re.split('\\blow\\b',string)[-1]
print(stringafterword)
' reading is seen as positive (or bullish) for the Korean Won.'
il codice generico è:
re.split('\\bTHE_WORD_YOU_WANT\\b',string)[-1]
Spero che questo possa aiutare qualcuno!
string.partition(" low ")[2]
? (Nota gli spazi su entrambi i lati dilow
In Python 3.9, removeprefix
viene aggiunto un nuovo metodo:
>>> 'TestHook'.removeprefix('Test')
'Hook'
>>> 'BaseTestCase'.removeprefix('Test')
'BaseTestCase'