Ich versuche, bestimmte Arten von E-Mail-Adressen der Form Benutzername @ Siteaddress zu finden, wobei Benutzername eine nicht leere Zeichenfolge mit einer Mindestlänge von 5 ist, die aus Zeichen {a-z A-Z 0-9 erstellt wird. _}. Der Benutzername darf nicht mit '.' Beginnen. oder '_' Die Site-Adresse besteht aus einem Präfix, bei dem es sich um eine nicht leere Zeichenfolge handelt, die aus Zeichen {az AZ 0-9} (ohne Klammern) gefolgt von einem der folgenden Suffixe {".com", ".org" besteht "," edu "," .co.in "}. Der folgende Code funktioniert nicht

list=re.findall("[a-zA-Z0-9][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._]*@[a-zA-Z0-9][a-zA-Z0-9]*\.(com|edu|org|co\.in)",raw_input())

Das Folgende funktioniert jedoch einwandfrei, wenn ich in der letzten Klammer ein '?:' Einfüge. Ich kann den Grund nicht herausfinden

list=re.findall("[a-zA-Z0-9][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._][a-zA-Z0-9._]*@[a-zA-Z0-9][a-zA-Z0-9]*\.(?:com|edu|org|co\.in)",raw_input())
2
user103260 30 Nov. 2013 im 23:02

3 Antworten

Beste Antwort

Bei Ihrer Frage geht es weniger um E-Mail-Matching als um das Verhalten von findall , was abhängig davon variiert, ob der reguläre Ausdruck Erfassungsgruppen enthält. Hier ist ein einfaches Beispiel:

import re

text = '123.com 456.edu 999.com'

a = r'\d+\.(com|edu)'    # A capturing group.
b = r'\d+\.(?:com|edu)'  # A non-capturing group.

print re.findall(a, text)  # Only the captures: ['com', 'edu', 'com']
print re.findall(b, text)  # The full matches: ['123.com', '456.edu', '999.com']

Ein schneller Scan der regulären Dokumentation kann sich lohnen für dich. Einige Punkte, die hier relevant erscheinen:

(?:...)  # Non-capturing group.
...{4,}  # Match something 4 or more times.
\w       # Word character.
\d       # Digit
1
FMc 30 Nov. 2013 im 19:38

Sie sollten Ihre eigene E-Mail-Adresse nicht regulieren - es ist notorisch schwierig, dies richtig zu machen. Eine Diskussion finden Sie unter http://www.regular-expressions.info/email.html zum Thema.

Um diesen Artikel zusammenzufassen, ist dies normalerweise gut genug: \b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

Dieser ist noch genauer (der Autor behauptet 99,99% der E-Mail-Adressen):

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@
(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

Und dies ist die Version, die buchstäblich allen möglichen RFC 5322 E-Mail-Adressen entspricht:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*
  |  "(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]
      |  \\[\x01-\x09\x0b\x0c\x0e-\x7f])*")
@ (?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
  |  \[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
       (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:
          (?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]
          |  \\[\x01-\x09\x0b\x0c\x0e-\x7f])+)
     \])

Der letzte ist eindeutig übertrieben, aber er gibt Ihnen eine Vorstellung von der Komplexität.

2
joews 30 Nov. 2013 im 19:08
\b[^\W_][\w.]{3,}[^\W_]@[^\W_]+\.(?:com|org|edu|co\.in)\b

Regular expression visualization

1
Ωmega 30 Nov. 2013 im 20:23