正規表現はやり過ぎかもしれません...あなたの問題の記述は正確には何ですか?何をキャプチャする必要がありますか?
私が捕まえたいくつかのこと(あなたの正規表現に現れる順序で;時々それを読むのに役立つ、左から右、英語スタイル):
([\w\s+]+)
これは、「1つ以上(文字または1つ以上のスペース)をキャプチャする」という意味です。
都市名の末尾のスペースを本当にキャプチャしますか?また、正規表現はすでに外側に基づいて1つ以上の記号と一致しているため、+
角かっこ内に1つ以上の記号は必要ありません(実際には必要ありません)。この部分を次のように書き直します。[ ]
+
([\w\s]*\w)
これは、最後の英数字(「ゼロ以上(文字またはスペース)の後に文字が続く」)まで熱心に一致します。これは、少なくとも1つの文字があることを前提としていますが、単一のスペースでも機能するという想定よりも優れています。
次にあります:
,?\s*\(?
これは、コンマまたは開いたパレンのいずれかが表示されることを保証しないことを除いて、私には問題ないように見えます。どうですか:
(?:,\s*\(|,\s*|\s*\()
これは、「(スペースがいくつかあり、次に開き括弧があるコンマ)OR(スペースがいくつかあるコンマ)OR(スペースがあり、次に開き括弧があるコンマ)のいずれかに非キャプチャー一致します。これにより、コンマまたはパレン、あるいはその両方が必要になります。
次に、最初の式と非常によく似たキャプチャ式があります。
([\w\s+\\/]+)
+
繰り返しになりますが、都市名の末尾にスペース(この場合はスラッシュ)を付けたり、内部にスペースを入れたりする必要はありません[ ]
。
([\w\s\\/]*\w)
次の表現は、おそらくvenezuel
a
問題が発生している場所です。見てみましょう:
\)?\s*\(?([\w\s+\\/]+)\)?
これはかなり長いので、分解してみましょう。
\)?\s*\(?
「多分近いパレン、そして多分いくつかのスペース、そして多分開いたパレンと一致する」と言います。これは大丈夫だと思います。本当の問題に移りましょう。
([\w\s+\\/]+)
このキャプチャグループは、少なくとも1つの文字と一致する必要があります。マッチャーがあなたの住所の最後に「ベネズエラ」を見つけた場合、それは熱心に文字と一致しvenezuel
、次にこの最終的な表現をそれが残したもので満たす必要がありa
ます。代わりに試してください:
\)?\s*
続いて、最終式全体をオプションにし、外側の式をキャプチャしないようにします。
(?:\(?([\w\s+\\/]+)\)?)?
最終的な式は次のようになります。
([\w\s]*\w)(?:,\s*\(|,\s*|\s*\()([\w\s\\/]*\w)\)?\s*(?:\(?([\w\s+\\/]+)\)?)?
編集:最終的なグループを2回キャプチャする問題を修正しました。1回はペアレンあり、もう1回はペアなしです。これで、parens内のテキストのみをキャプチャする必要があります。
あなたの例でそれをテストします:
>>> re.match(r, 'caracas, venezuela').groups()
('caracas', 'venezuela', None)
>>> re.match(r, 'caracas (venezuela)').groups()
('caracas', 'venezuela', None)
>>> re.match(r, 'caracas, (venezuela) (df)').groups()
('caracas', 'venezuela', 'df')