Đây là cách thực hiện của tôi, nhanh hơn và đầy đủ hơn nhiều so với các câu trả lời khác ở đây. Nó có 4 chức năng con riêng biệt cho các trường hợp khác nhau.
Tôi sẽ chỉ sao chép chuỗi doc của str_split
hàm chính :
str_split(s, *delims, empty=None)
Chia chuỗi s
theo phần còn lại của các đối số, có thể bỏ qua các phần trống ( empty
đối số từ khóa chịu trách nhiệm về điều đó). Đây là một chức năng máy phát điện.
Khi chỉ có một dấu phân cách được cung cấp, chuỗi chỉ đơn giản được phân tách bởi nó.
empty
sau đó là True
theo mặc định.
str_split('[]aaa[][]bb[c', '[]')
-> '', 'aaa', '', 'bb[c'
str_split('[]aaa[][]bb[c', '[]', empty=False)
-> 'aaa', 'bb[c'
Khi cung cấp nhiều dấu phân cách, chuỗi được chia theo chuỗi dài nhất có thể của các dấu phân cách đó theo mặc định, hoặc, nếu empty
được đặt thành
True
, các chuỗi trống giữa các dấu phân cách cũng được bao gồm. Lưu ý rằng các dấu phân cách trong trường hợp này có thể chỉ là các ký tự đơn.
str_split('aaa, bb : c;', ' ', ',', ':', ';')
-> 'aaa', 'bb', 'c'
str_split('aaa, bb : c;', *' ,:;', empty=True)
-> 'aaa', '', 'bb', '', '', 'c', ''
Khi không có dấu phân cách nào được cung cấp, string.whitespace
được sử dụng, do đó, hiệu ứng giống như str.split()
, ngoại trừ hàm này là một trình tạo.
str_split('aaa\\t bb c \\n')
-> 'aaa', 'bb', 'c'
import string
def _str_split_chars(s, delims):
"Split the string `s` by characters contained in `delims`, including the \
empty parts between two consecutive delimiters"
start = 0
for i, c in enumerate(s):
if c in delims:
yield s[start:i]
start = i+1
yield s[start:]
def _str_split_chars_ne(s, delims):
"Split the string `s` by longest possible sequences of characters \
contained in `delims`"
start = 0
in_s = False
for i, c in enumerate(s):
if c in delims:
if in_s:
yield s[start:i]
in_s = False
else:
if not in_s:
in_s = True
start = i
if in_s:
yield s[start:]
def _str_split_word(s, delim):
"Split the string `s` by the string `delim`"
dlen = len(delim)
start = 0
try:
while True:
i = s.index(delim, start)
yield s[start:i]
start = i+dlen
except ValueError:
pass
yield s[start:]
def _str_split_word_ne(s, delim):
"Split the string `s` by the string `delim`, not including empty parts \
between two consecutive delimiters"
dlen = len(delim)
start = 0
try:
while True:
i = s.index(delim, start)
if start!=i:
yield s[start:i]
start = i+dlen
except ValueError:
pass
if start<len(s):
yield s[start:]
def str_split(s, *delims, empty=None):
"""\
Split the string `s` by the rest of the arguments, possibly omitting
empty parts (`empty` keyword argument is responsible for that).
This is a generator function.
When only one delimiter is supplied, the string is simply split by it.
`empty` is then `True` by default.
str_split('[]aaa[][]bb[c', '[]')
-> '', 'aaa', '', 'bb[c'
str_split('[]aaa[][]bb[c', '[]', empty=False)
-> 'aaa', 'bb[c'
When multiple delimiters are supplied, the string is split by longest
possible sequences of those delimiters by default, or, if `empty` is set to
`True`, empty strings between the delimiters are also included. Note that
the delimiters in this case may only be single characters.
str_split('aaa, bb : c;', ' ', ',', ':', ';')
-> 'aaa', 'bb', 'c'
str_split('aaa, bb : c;', *' ,:;', empty=True)
-> 'aaa', '', 'bb', '', '', 'c', ''
When no delimiters are supplied, `string.whitespace` is used, so the effect
is the same as `str.split()`, except this function is a generator.
str_split('aaa\\t bb c \\n')
-> 'aaa', 'bb', 'c'
"""
if len(delims)==1:
f = _str_split_word if empty is None or empty else _str_split_word_ne
return f(s, delims[0])
if len(delims)==0:
delims = string.whitespace
delims = set(delims) if len(delims)>=4 else ''.join(delims)
if any(len(d)>1 for d in delims):
raise ValueError("Only 1-character multiple delimiters are supported")
f = _str_split_chars if empty else _str_split_chars_ne
return f(s, delims)
Hàm này hoạt động trên Python 3 và một bản sửa lỗi dễ dàng, mặc dù khá xấu, có thể được áp dụng để làm cho nó hoạt động ở cả phiên bản 2 và 3. Các dòng đầu tiên của hàm nên được thay đổi thành:
def str_split(s, *delims, **kwargs):
"""...docstring..."""
empty = kwargs.get('empty')