2012-02-06 10 views
1

私は、文字列(データベース接続URI)を取り、Pythonの正規表現 -

​​

これは正常に動作し、パスワードなどのユーザー名に名前のグループを使用して、それを分割Pythonの正規表現を持って脱出。問題は、パスワードとホストを分割するためにuriに@記号がある場合です。たとえば、

uri = 'username:[email protected]@host/database' 

は一致しません。しかし、私は特殊文字をエスケープすることができます。例えば、

uri = 'username:p\@[email protected]/database' 

と一致するようにしたいと思います。私の正規表現の経験はかなり限られている - 私は私は何をしたいのですが、それはそれは\文字が先行していますしない限り、@はありません任意の文字に一致するように

(?P<password>[^@]*) 

グループを変更していると思います。もちろん、(ほとんどの)接続文字列には\ @がまったく含まれません。

ご迷惑をおかけして申し訳ございません。

あなたが行うことができ
+2

最初にURLエンコードされないのはなぜですか? –

+0

わかりませんが、それはもともと自分のコードではありません。それは実際にweb2pyからです。とにかく、URLエンコードされている、つまり@が%40に置き換えられた場合、私は同じ問題を抱えていませんか?彼らはまだエスケープする必要があります.. – Caligari

+0

いいえ、正規表現エンジンはURLデコードしないためです。 –

答えて

0

私のテイクはあなたが貪欲なマッチングをしたいです、それは、パスワードが最後@アップであるとホスト名は、最後の@と第一/

簡単なの間にあります方法は次のようになります:

In [68]: re.match('((?P<user>.*):)((?P<pass>.*)@)((?P<host>.*)/)((?P<db>.*))', "username:[email protected]@host/data").groupdict() 
Out[68]: {'db': 'data', 'host': 'host', 'pass': '[email protected]', 'user': 'username'} 

あなたはオプションの追加が必要な場合があります。ユーザー名とパスワードは省略できます。

+0

ありがとう。良い答えがありますが、これはまさに私が後にしたものです。ありがとう。 – Caligari

0

(?P<password>([^\\@]|\\.)*) 

これはあなたの文字列をスキャンし、どちらかと一致します。\非または非@、またはそれがあまりにも続くものと一致した場合には、バックスラッシュを。唯一の方法は、 '@'が正規表現でマッチすることができるのは、それが\\.正規表現を介して侵入した場合、つまりエスケープされた場合です。

これ以外にも、Pythonで正規表現を書くには、r "insert_regex_here"を使用します。

正規表現の場合\\.の場合は、"\\\\."のようにPythonで記述する必要があります。あなたができることを避けるためにr"\\."

0

私はあなたがre.splitを使用することをお勧めします:

>>> print re.split(r"(?<!\\)@|/|:", r"username:[email protected]/database") 
['username', 'password', 'host', 'database'] 
>>> print re.split(r"(?<!\\)@|/|:", r"username:p\@[email protected]/database") 
['username', 'p\\@ssword', 'host', 'database']