2015-12-16 9 views
6
import re 

s = 'PythonCookbookListOfContents' 

# the first line does not work 
print re.split('(?<=[a-z])(?=[A-Z])', s) 

# second line works well 
print re.sub('(?<=[a-z])(?=[A-Z])', ' ', s) 

# it should be ['Python', 'Cookbook', 'List', 'Of', 'Contents'] 

小文字と大文字の境界から文字列を分割するにはどうすればよいですか?Pythonはゼロ幅のアンカーを分割できません。

2行目が正常に動作しているのに、1行目が動作しないのはなぜですか? re.splitによると

答えて

8

:分割が空のパターンマッチで文字列を分割することはありませんことを

注意。たとえば :

>>> re.split('x*', 'foo') 
['foo'] 
>>> re.split("(?m)^$", "foo\n\nbar\n") 
['foo\n\nbar\n'] 

どう代わりre.findallを使用してはどうですか? (代わりに、セパレータに焦点を当て、あなたが取得したい項目に焦点を当てています。)

>>> import re 
>>> s = 'PythonCookbookListOfContents' 
>>> re.findall('[A-Z][a-z]+', s) 
['Python', 'Cookbook', 'List', 'Of', 'Contents'] 

UPDATE

は(再交換するために、代替正規表現モジュール)regex moduleを使用して、あなたが分割することができますゼロ幅のマッチ:

>>> import regex 
>>> s = 'PythonCookbookListOfContents' 
>>> regex.split('(?<=[a-z])(?=[A-Z])', s, flags=regex.VERSION1) 
['Python', 'Cookbook', 'List', 'Of', 'Contents'] 

:SPを有効にするには、regex.VERSION1フラグを指定しますゼロで長さが一致する動作。

+0

もちろん、findallを使って単語を見つけることはできますが、大文字と小文字の境界に応じて分割する方法はありますか?状況が変わったときにこの問題を処理する必要があり、枠に合わせるために幅がゼロのアンカーを使用する必要があります。 – Booster

+0

あなたはアンカーによって配列を意味しますか? – Onilol

+0

私は先を見て、背後を見て、つまり '?<='と '?='を意味します。 @Onilol – Booster

関連する問題