のような文字列があり、
それをに"Let's split this string into many small ones"
分割したいとします。this
into
ones
出力は次のようになります。
["Let's split", "this string", "into many small", "ones"]
それを行うための最も効率的な方法は何ですか?
先読みで。
>>> re.split(r'\s(?=(?:this|into|ones)\b)', "Let's split this string into many small ones")
["Let's split", 'this string', 'into many small', 'ones']
を使用してre.split()
:
>>> re.split(r'(this|into|ones)', "Let's split this string into many small ones")
["Let's split ", 'this', ' string ', 'into', ' many small ', 'ones', '']
分割する単語をキャプチャグループに入れることにより、出力には分割した単語が含まれます。
スペースを削除する必要がある場合は、出力で使用map(str.strip, result)
します。re.split()
>>> map(str.strip, re.split(r'(this|into|ones)', "Let's split this string into many small ones"))
["Let's split", 'this', 'string', 'into', 'many small', 'ones', '']
filter(None, result)
必要に応じて、空の文字列を削除するために使用できます。
>>> filter(None, map(str.strip, re.split(r'(this|into|ones)', "Let's split this string into many small ones")))
["Let's split", 'this', 'string', 'into', 'many small', 'ones']
単語を分割して次のグループに関連付けたままにするには、代わりに先読みアサーションを使用する必要があります。
>>> re.split(r'\s(?=(?:this|into|ones)\b)', "Let's split this string into many small ones")
["Let's split", 'this string', 'into many small', 'ones']
今、私たちは実際に空白で分割していますが、その後に単語全体が続く空白だけthis
で、、、into
およびのセットに1つありones
ます。
これを行うにはかなり怠惰な方法があります:
import re
def resplit(regex,s):
current = None
for x in regex.finditer(s):
start = x.start()
yield s[current:start]
current = start
yield s[start:]
s = "Let's split this string into many small ones"
regex = re.compile('(this|into|ones)')
print list( resplit(regex,s) )
これが最も効率的かどうかはわかりませんが、かなりきれいです。
基本的には、一度に1ピースずつ、試合を繰り返すだけです。ピースはs
、正規表現が一致し始める文字列()のインデックスによって決定されます。そのポイントまで文字列を切り刻み、そのインデックスを次のスライスの開始ポイントとして保存します。
パフォーマンスに関しては、ignacioがこのラウンドで明らかに勝ちます。
9.1412050724 -- Me
3.09771895409 -- ignacio
コード:
import re
def resplit(regex,s):
current = None
for x in regex.finditer(s):
start = x.start()
yield s[current:start]
current = start
yield s[start:]
def me(regex,s):
return list(resplit(regex,s))
def ignacio(regex,s):
return regex.split("Let's split this string into many small ones")
s = "Let's split this string into many small ones"
regex = re.compile('(this|into|ones)')
regex2 = re.compile(r'\s(?=(?:this|into|ones)\b)')
import timeit
print timeit.timeit("me(regex,s)","from __main__ import me,regex,s")
print timeit.timeit("ignacio(regex2,s)","from __main__ import ignacio,regex2,s")