2017-11-11 147 views
3

例子:如果有積極的lookahead和積極的lookbehind而不是分隔符,我該如何分割一個字符串?

s = "Thisissometext andthisissometext" 

我想之間的文本拆分 「是」 和 「一些」:

["Thisis", "sometext andthisis", "sometext"] 

如果我這樣做:

re.split("(?<=is)s(?=ome)", s) 
--> ['Thisis', 'ometext andthisis', 'ometext'] 

沒有 'S'

如果我這樣做

re.split("(?<=is)(s)(?=ome)", s) 
--> ['Thisis', 's', 'ometext andthisis', 's', 'ometext'] 

如果我這樣做

re.split("(?<=is)(?=some)", s) 
--> ValueError: split() requires a non-empty pattern match. 

我怎麼可以拆分如果沒有分隔字符串?

回答

3

您需要支持空分裂的新regex module

import regex as re 

s = "Thisissometext andthisissometext" 

print(re.split(r"(?V1)(?<=is)(?=some)", s)) 
# ['Thisis', 'sometext andthisis', 'sometext'] 

注意這裏的(?V1)這使新的行爲。這可以通過一個標誌設置,以及:

print(re.split(r"(?<=is)(?=some)", s, flags = re.VERSION1)) 
+2

Hoi Jan,很好的解決方案!從來沒有聽說過'(?V1)'哇。 – Reman

+2

@Reman:很高興幫助。在答案的底部提供了另一種選擇。 – Jan

1

而不是使用split的,這裏要說的是,你可以在re.findall使用,讓您的工作做了一個正則表達式:

>>> s = "Thisissometext andthisissometext" 
>>> print re.findall(r'[\w\s]+?(?:is(?=some)|$)', s) 
['Thisis', 'sometext andthisis', 'sometext'] 

RegEx Demo

RegEx分手:

  • [\w\s]+?:匹配1+字或空格字符(非貪婪
  • (?::啓動非捕獲組
    • is:匹配字面is
    • (?=some):即必須跟some
    • |:或
    • $:它是字符串的結尾
  • ):結束非捕獲組
2

一種簡單和快捷的方法,如果你知道在文本中不存在的人物,'@'這裏它的工作原理:

s.replace('issome','[email protected]').split('@') 
# ['Thisis', 'sometext andthisis', 'sometext'] 

測試:

In [300]: %timeit s.replace('issome','[email protected]').split('@') 
976 ns ± 21.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) 

In [301]: %timeit regex.split(r"(?V1)(?<=is)(?=some)", s) 
7.36 µs ± 145 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 

In [302]: %timeit re.findall(r'[\w\s]+?(?:is(?=some)|$)', s) 
4.28 µs ± 97.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 
+0

感謝您的解決方案。非常好,但有時我需要正則表達式來分割我的字符串。 – Reman

+0

加上一個爲timit! – Jan