2011-08-12 13 views
2

と@文字の前に私は、メールアドレスのローカル部分に一致するようにしようとしている:と先読みおよび非キャプチャ正規表現

LOCAL_RE_NOTQUOTED = """ 
((
\w   # alphanumeric and _ 
| [!#$%&'*+-/=?^_`{|}~]   # special chars, but no dot at beginning 
) 
(
\w   # alphanumeric and _ 
| [!#$%&'*+-/=?^_`{|}~]   # special characters 
| ([.](?![.])) # negative lookahead to avoid pairs of dots. 
)*) 
(?<!\.)(?:@)   # no end with dot before @ 
""" 

テスト:

re.match(LOCAL_RE_NOTQUOTED, "[email protected]", re.VERBOSE).group() 

が得られます。

'[email protected]' 

非キャプチャグループを使用していても@が出力に印刷されるのはなぜですか(?:@)

テスト:

re.match(LOCAL_RE_NOTQUOTED, "[email protected]", re.VERBOSE).groups() 

ができます:

('a.a..a', 'a', 'a', None) 

はなぜ正規表現は、ドット'..'一対の文字列を拒否していないのですか?

+0

'/([\ S] +)@/g'のような単純な正規表現を使用し、次のステップで不要なガベージからの出力をフィルタリングする方が簡単な場合があります –

+0

@Jakub、あまりにも簡単です。 :)まだ、私はなぜそれが動作しないのだろうかと思っています... – morfys

+0

正規表現の '#'文字はエスケープしてはいけませんか? (コードの第4行と第8行) –

答えて

5

非キャプチャグループ(?:...)と先読みアサーション(?=...)が混乱しています。

前者は試合に参加しています(したがって全体一致を含むmatch.group()の一部です)、後で使用するために逆参照を生成しません(後で使用するために$1など)。

2つ目の問題(なぜダブルドットがマッチするのですか)はやや難解です。これはあなたの正規表現のエラーのためです。あなたは+/間の文字にマッチ」を書いた、とASCIIでは、ドットが右彼ら(:+,-./ ASCII 43-47)との間にある

[+-/] 

(ポイントを作るために短縮)あなたが書いたとき、参照してください。そのため、最初の文字クラスは、ドットと一致し、先読みアサーションはあなたがリテラルダッシュとしてそれを治療するための文字クラスの最後にダッシュを配置する必要は到達しません:。

((
\w   # alphanumeric and _ 
| [!#$%&'*+/=?^_`{|}~-]   # special chars, but no dot at beginning 
) 
(
\w   # alphanumeric and _ 
| [!#$%&'*+/=?^_`{|}~-]   # special characters 
| ([.](?![.])) # negative lookahead to avoid pairs of dots. 
)*) 
(?<!\.)([email protected])   # no end with dot before @ 

そしてもちろん、このロジックを使用する場合は、少し簡素化できます。

^(?!\.)     # no dot at the beginning 
(?: 
[\w!#$%&'*+/=?^_`{|}~-] # alnums or special characters except dot 
| (\.(?![[email protected]]))   # or dot unless it's before a dot or @ 
)* 
([email protected])      # end before @ 
+1

お返事いただきありがとうございます。あなたは私の正規表現でエラーを検出するために信じられないです... – morfys

関連する問題