[英]How do I split a string with several delimiters, but only once on each delimiter? Python
我正在嘗試拆分一個字符串,例如下面的字符串,所有分隔符都在下面,但只有一次。
string = 'it; seems; like\ta good\tday to watch\va\vmovie.'
delimiters = '\t \v;'
在這種情況下,output 將是:
['it', ' seems; like', 'a good\tday to watch', 'a\vmovie.']
顯然上面的例子是一個無意義的例子,但我試圖了解這是否可能。 一個相當復雜的正則表達式是否合適?
如果之前有人問過這個問題,我們深表歉意。 我進行了相當多的搜索,但找不到與我的示例非常相似的東西。 謝謝你的時間!
這應該可以解決問題:
import re
def split_once_by(s, delims):
delims = set(delims)
parts = []
while delims:
delim_re = '({})'.format('|'.join(re.escape(d) for d in delims))
result = re.split(delim_re, s, maxsplit=1)
if len(result) == 3:
first, delim, s = result
parts.append(first)
delims.remove(delim)
else:
break
parts.append(s)
return parts
例子:
>>> split_once_by('it; seems; like\ta good\tday to watch\va\vmovie.', '\t\v;')
['it', ' seems; like', 'a good\tday to watch', 'a\x0bmovie.']
Burning Alcohol 的回答啟發了我更好地寫這個(IMO)function:
def split_once_by(s, delims):
split_points = sorted((s.find(d), -len(d), d) for d in delims)
start = 0
for stop, _longest_first, d in split_points:
if stop < start: continue
yield s[start:stop]
start = stop + len(d)
yield s[start:]
用法:
>>> list(split_once_by('it; seems; like\ta good\tday to watch\va\vmovie.', '\t\v;'))
['it', ' seems; like', 'a good\tday to watch', 'a\x0bmovie.']
只需創建一個模式列表並應用它們一次:
string = 'it; seems; like\ta good\tday to watch\va\vmovie.'
patterns = ['\t', '\v', ';']
for pattern in patterns:
string = '*****'.join(string.split(pattern, maxsplit=1))
print(string.split('*****'))
Output:
['it', ' seems; like', 'a good\tday to watch', 'a\x0bmovie.']
那么,什么是"*****"
??
在每次迭代中,當您應用split
方法時,您會得到一個列表。 因此,在下一次迭代中,您不能應用.split ()
方法(因為您有一個列表),因此您必須將該列表的每個值與一些奇怪的字符連接起來,例如"****"
或"@@@"
或"^^^^^^^"
或任何您想要的,以便在下一次迭代中重新應用 split ()。 最后,對於字符串中的每個"*****"
,您將擁有一個列表模式,因此您可以使用它來進行最終拆分。
一個簡單的算法就可以了,
test_string = r'it; seems; like\ta good\tday to watch\va\vmovie.'
delimiters = [r'\t', r'\v', ';']
# find the index of each first occurence and sort it
delimiters = sorted(delimiters, key=lambda delimiter: test_string.find(delimiter))
splitted_string = [test_string]
# perform split with option maxsplit
for index, delimiter in enumerate(delimiters):
if delimiter in splitted_string[-1]:
splitted_string += splitted_string[-1].split(delimiter, maxsplit=1)
splitted_string.pop(index)
print(splitted_string)
# ['it', ' seems; like', 'a good\\tday to watch', 'a\\vmovie.']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.