Данаил обнови решението на 23.04.2014 05:17 (преди над 10 години)
+import re
+
+EMAIL_NAME = r"[a-zA-Z0-9][\w\+\.\-]{0,200}@"
+TLD = r"[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?"
+HOST_NAME = r"([a-zA-Z0-9][a-zA-Z0-9\-]{0,62}(?<!\-)\.)+"
+HOST_AND_TLD = HOST_NAME + TLD
+EMAIL = EMAIL_NAME + HOST_NAME + TLD + r"(?=\b)"
+
+LOCAL_PREFFIX = r"(?<![a-zA-Z0-9\+])0(?!0)"
+INTERNATIONAL_PREFFIX = r"(((?<=\b)00)|\+)(?!0)[0-9]{1,3}"
+PHONE_PREFFIX = "(" + LOCAL_PREFFIX + "|" + INTERNATIONAL_PREFFIX + ")"
+PHONE_BODY = r"([\s\-\(\)]{0,2}[0-9]){6,11}"
+PHONE_NUMBER = PHONE_PREFFIX + PHONE_BODY + r"(?![0-9])"
+
+IP_ADDRESS = r"(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}" + \
+ "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
+NUMBER = r"(-)?(0|([1-9][0-9]*))(\.[1-9][0-9]*)?"
+INTEGER = r"(-)?(0|([1-9][0-9]*))"
+DATE = r"[0-9]{4}\-(([0][1-9])|([1][0-2]))\-((0[1-9])|([1-2][0-9])|([3][0-1]))"
+TIME = r"(([0-1][0-9])|([2][0-3])):[0-5][0-9]:[0-5][0-9]"
+DATETIME = "(" + DATE + r"(\s|T)" + TIME + ")"
+
+
+class PrivacyFilter:
+ def __init__(self, text):
+ self.text = text
+ self.preserve_phone_country_code = False
+ self.preserve_email_hostname = False
+ self.partially_preserve_email_username = False
+
+ def filtered(self):
+ filtered_text = self.filtered_email(self.text)
+ filtered_text = self.filtered_phone(filtered_text)
+ return filtered_text
+
+ def filtered_email(self, e_address):
+ return re.sub(EMAIL, self.get_email_substitutions, e_address)
+
+ def get_email_substitutions(self, e_address):
+ e_address = e_address.group(0)
+ filtered_address = ""
+ if not self.partially_preserve_email_username:
+ if not self.preserve_email_hostname:
+ return "[EMAIL]"
+ if self.partially_preserve_email_username or self.preserve_email_hostname:
+ filtered_address = re.sub(EMAIL_NAME, "[FILTERED]@", e_address)
+ if self.partially_preserve_email_username:
+ if (len(re.search(EMAIL_NAME, e_address).group(0)) > 6):
+ filtered_address = e_address[:3] + filtered_address
+ return filtered_address
+
+ def filtered_phone(self, phone):
+ return re.sub(PHONE_NUMBER, self.get_phone_substitutions, phone)
+
+ def get_phone_substitutions(self, phone):
+ phone = phone.group(0)
+ if self.preserve_phone_country_code:
+ code = re.search(INTERNATIONAL_PREFFIX, phone)
+ if code is not None:
+ return phone[:len(code.group(0))] + " [FILTERED]"
+ return "[PHONE]"
+
+
+class Validations:
+ def is_email(value):
+ return re.match(EMAIL + "\Z", value) is not None
+
+ def is_phone(value):
+ return re.match(PHONE_NUMBER + "\Z", value) is not None
+
+ def is_hostname(value):
+ return re.match(HOST_AND_TLD + '\Z', value) is not None
+
+ def is_ip_address(value):
+ return re.match(IP_ADDRESS + '\Z', value) is not None
+
+ def is_number(value):
+ return re.match(NUMBER + '\Z', value) is not None
+
+ def is_integer(value):
+ return re.match(INTEGER + '\Z', value) is not None
+
+ def is_date(value):
+ return re.match(DATE + '\Z', value) is not None
+
+ def is_time(value):
+ return re.match(TIME + '\Z', value) is not None
+
+ def is_datetime(value):
+ return re.match(DATETIME + '\Z', value) is not None