我们知道anchors
,word boundaries
和lookaround
匹配一个位置,而不是匹配一个字符。
是否可以使用前面的方法之一用正则表达式(特别是在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
解决它是否可能?
答案 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]
参见演示。
答案 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)