按位置拆分字符串而不是字符

时间:2015-04-07 16:29:33

标签: python regex split

我们知道anchorsword boundarieslookaround匹配一个位置,而不是匹配一个字符。
是否可以使用前面的方法之一用正则表达式(特别是在python中)分割字符串?

例如,请考虑以下字符串:

"ThisisAtestForchEck,Match IngwithPosition." 

所以我想要以下结果(以大写字母开头但不以空格开头的子字符串):

['Thisis', 'Atest', 'Forch' ,'Eck,' ,'Match Ingwith' ,'Position.']

如果我分组我得到:

>>> re.split(r'([A-Z])',s)
['', 'T', 'hisis', 'A', 'test', 'F', 'orch', 'E', 'ck,', 'M', 'atchingwith', 'P', 'osition.']

这是环顾四周的结果:

>>> re.split(r'(?<=[A-Z])',s)
['ThisisAtestForchEck,MatchingwithPosition.']
>>> re.split(r'((?<=[A-Z]))',s)
['ThisisAtestForchEck,MatchingwithPosition.']
>>> re.split(r'((?<=[A-Z])?)',s)
['ThisisAtestForchEck,MatchingwithPosition.']

请注意,如果我想通过以大写字母开头且前面有空格的子字符串进行拆分,例如:

['Thisis', 'Atest', 'Forch' ,'Eck,' ,'Match ', Ingwith' ,'Position.']

我可以使用re.findall,即:

>>> re.findall(r'([A-Z][^A-Z]*)',s)
['Thisis', 'Atest', 'Forch', 'Eck,', 'Match ', 'Ingwith', 'Position.']

但是第一个例子呢:用re.findall解决它是否可能?

4 个答案:

答案 0 :(得分:2)

 (?<!\s)(?=[A-Z])

你可以使用它来拆分regex模块,因为re不支持以0宽度断言进行拆分。

import regex
x="ThisisAtestForchEck,Match IngwithPosition."
print regex.split(r"(?<![\s])(?=[A-Z])",x,flags=regex.VERSION1)

print [i for i in regex.split(r"(?<![\s])(?=[A-Z])",x,flags=regex.VERSION1) if i]

参见演示。

https://regex101.com/r/sJ9gM7/65

答案 1 :(得分:2)

使用re.findall的方式:

re.findall(r'(?:[A-Z]|^[^A-Z\s])[^A-Z\s]*(?:\s+[A-Z][^A-Z]*)*',s)

当您决定将您的方法从split更改为findall时,第一项工作就是重新制定您的要求:&#34;我希望将每个大写字母上的字符串拆分为非{空间&#34; =&GT; &#34;我希望找到一个或多个以空格开头的子字符串,以字母开头的大写字母开头(如果字符串不以大写字母开头) &#34;

答案 2 :(得分:1)

我知道这可能不太方便,因为结果的元组性质。但我认为这findall找到了你需要的东西:

re.findall(r'((?<!\s)[A-Z]([^A-Z]|(?<=\s)[A-Z])*)', s)
## returns [('Thisis', 's'), ('Atest', 't'), ('Forch', 'h'), ('Eck,', ','), ('Match Ingwith', 'h'), ('Position.', '.')]

这可以在以下列表推导中使用,以提供所需的输出:

[val[0] for val in re.findall(r'((?<!\s)[A-Z]([^A-Z]|(?<=\s)[A-Z])*)', s)]
## returns ['Thisis', 'Atest', 'Forch', 'Eck,', 'Match Ingwith', 'Position.']

这是一个使用split

的黑客攻击
re.split(r'((?<!\s)[A-Z]([^A-Z]|(?<=\s)[A-Z])*)', s)[1::3]
## returns ['Thisis', 'Atest', 'Forch', 'Eck,', 'Match Ingwith', 'Position.']

答案 3 :(得分:0)

尝试使用此模式进行捕获

([A-Z][a-z]*(?: [A-Z][a-z]*)*)

Demo