Решение на Регулярни изрази от Димитър Желев

Обратно към всички решения

Към профила на Димитър Желев

Резултати

  • 7 точки от тестове
  • 0 бонус точки
  • 7 точки общо
  • 26 успешни тест(а)
  • 13 неуспешни тест(а)

Код

import re
RULES_FOR_FILTRATION = {"EMAIL": "[EMAIL]",
"PHONE": "[PHONE]",
"PARTIAL": "[FILTERED]"}
HOSTNAME_PATTERN = "(?P<hostname>([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+" + \
"[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)"
EMAIL_USERNAME_PATTERN = "(?P<username>[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{0,200})"
EMAIL_PATTERN = EMAIL_USERNAME_PATTERN + "[@]" + HOSTNAME_PATTERN
PHONE_SEPARATOR = "[\s\(\)-]"
PHONE_CODE_PATTERN = "((?P<code>(00|\+)[1-9][0-9]{0,2})|0)"
PHONE_BASE_PATTERN = "" + \
"(?(code)" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?|" + \
"(" + PHONE_SEPARATOR + "?[1-9]" + PHONE_SEPARATOR + "?|" + \
PHONE_SEPARATOR + "[0-9]" + PHONE_SEPARATOR + "?))" + \
"(" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?){4,9}" + \
PHONE_SEPARATOR + "?[0-9]"
PHONE_PATTERN = "(" + PHONE_CODE_PATTERN + PHONE_BASE_PATTERN + ")"
IP_ADDRESS_PATTERN = "((\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))" + \
"(\.(\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))){3})"
NUMBER_PATTERN = "([-]?(0|[1-9]\d*)(\.\d+)?)"
INTEGER_PATTERN = "([-]?(0|[1-9]\d*))"
DATE_PATTERN = "(\d{4}[-](0\d|1[0-2])[-]([0-2]\d|3[0-1]))"
TIME_PATTERN = "(([0-1]\d|2[0-3])([:][0-5]\d){2})"
DATETIME_PATTERN = DATE_PATTERN + "[\s:T-]" + TIME_PATTERN
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):
text = self.text[:]
text = self.__filter_email(text)
text = self.__filter_phone(text)
return text
def __filter_email(self, text):
if self.partially_preserve_email_username:
return re.sub(EMAIL_PATTERN,
lambda match:
RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ match.group("hostname")
if len(match.group("username")) < 6
else match.group("username")[0:3] +
RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ match.group("hostname"),
text)
if self.preserve_email_hostname:
return re.sub(EMAIL_PATTERN,
RULES_FOR_FILTRATION['PARTIAL'] + r"@\g<hostname>",
text)
if not(self.preserve_email_hostname
or self.partially_preserve_email_username):
return re.sub(
EMAIL_PATTERN, RULES_FOR_FILTRATION['EMAIL'], text)
def __filter_phone(self, text):
if self.preserve_phone_country_code:
return re.sub("((?<=[\s\(\)-])|^)" + PHONE_PATTERN,
lambda match:
RULES_FOR_FILTRATION["PHONE"]
if match.group("code") is None
else match.group("code") + " "
+ RULES_FOR_FILTRATION['PARTIAL'],
text)
else:
return re.sub(
"((?<=[\s\(\)-])|^)" + PHONE_PATTERN, RULES_FOR_FILTRATION['PHONE'], text)
class Validations:
#
@classmethod
def is_email(cls, value):
if re.search("^" + EMAIL_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_phone(cls, value):
if re.search("^" + PHONE_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_hostname(cls, value):
if re.search("^" + HOSTNAME_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_ip_address(cls, value):
if re.search("^" + IP_ADDRESS_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_number(cls, value):
if re.search("^" + NUMBER_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_integer(cls, value):
if re.search("^" + INTEGER_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_date(cls, value):
if re.search("^" + DATE_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_time(cls, value):
if re.search("^" + TIME_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_datetime(cls, value):
if re.search("^" + DATETIME_PATTERN + "$", value) is None:
return False
return True

Лог от изпълнението

...FFF.F..F.....F..F..FF..FF...FF......
======================================================================
FAIL: test_does_not_filter_invalid_emails (test.PrivacyFilterTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 48, in test_does_not_filter_invalid_emails
    self.assertEqual(text, solution.PrivacyFilter(text).filtered())
AssertionError: 'Contact me here: _invalid@email.com' != 'Contact me here: _[EMAIL]'
- Contact me here: _invalid@email.com
+ Contact me here: _[EMAIL]


======================================================================
FAIL: test_does_not_filter_invalid_phone_numbers (test.PrivacyFilterTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 86, in test_does_not_filter_invalid_phone_numbers
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: 'Reach me at: 0885123' != 'Reach me at: [PHONE]'
- Reach me at: 0885123
+ Reach me at: [PHONE]


======================================================================
FAIL: test_filters_more_complex_phone_numbers (test.PrivacyFilterTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 76, in test_filters_more_complex_phone_numbers
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: '[PHONE]' != '+1 (555) 123-456-99'
- [PHONE]
+ +1 (555) 123-456-99


======================================================================
FAIL: test_obfuscates_more_complicated_emails (test.PrivacyFilterTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 37, in test_obfuscates_more_complicated_emails
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: '[EMAIL]' != 'larodi@x.com'
- [EMAIL]
+ larodi@x.com


======================================================================
FAIL: test_separates_preserved_country_code_from_filtered_phone_with_a_space (test.PrivacyFilterTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 100, in test_separates_preserved_country_code_from_filtered_phone_with_a_space
    self.assertEqual(filtered, filter.filtered())
AssertionError: 'Phone: +25 [FILTERED]' != 'Phone: +2 [FILTERED]'
- Phone: +25 [FILTERED]
?          -
+ Phone: +2 [FILTERED]


======================================================================
FAIL: test_can_validate_more_complex_phone_numbers (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 160, in test_can_validate_more_complex_phone_numbers
    self.assertIs(solution.Validations.is_phone(phone), valid)
AssertionError: True is not False

======================================================================
FAIL: test_does_not_allow_zero_months_or_days_in_dates (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 249, in test_does_not_allow_zero_months_or_days_in_dates
    self.assertFalse(solution.Validations.is_date('1000-00-01'))
AssertionError: True is not false

======================================================================
FAIL: test_handles_multiline_strings_in_IP_validation_properly (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 189, in test_handles_multiline_strings_in_IP_validation_properly
    self.assertFalse(solution.Validations.is_ip_address("8.8.8.8\n"))
AssertionError: True is not false

======================================================================
FAIL: test_handles_multiline_strings_in_hostname_validation_properly (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 179, in test_handles_multiline_strings_in_hostname_validation_properly
    self.assertFalse(solution.Validations.is_hostname("foo.com\n"))
AssertionError: True is not false

======================================================================
FAIL: test_handles_newlines_in_date_validation (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 259, in test_handles_newlines_in_date_validation
    self.assertFalse(solution.Validations.is_date("2012-11-19\n"))
AssertionError: True is not false

======================================================================
FAIL: test_handles_newlines_in_time_and_datetime_validation (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 288, in test_handles_newlines_in_time_and_datetime_validation
    self.assertFalse(solution.Validations.is_time("12:01:01\n"))
AssertionError: True is not false

======================================================================
FAIL: test_validates_datetime_values (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 281, in test_validates_datetime_values
    self.assertFalse(solution.Validations.is_datetime('2012-00-19T23:59:00'))
AssertionError: True is not false

======================================================================
FAIL: test_validates_hostnames (test.ValidationsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20140513-11348-1et37zj/test.py", line 169, in test_validates_hostnames
    self.assertTrue(solution.Validations.is_hostname('1.2.3.4.xip.io'))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 39 tests in 0.048s

FAILED (failures=13)

История (2 версии и 0 коментара)

Димитър обнови решението на 23.04.2014 01:11 (преди над 10 години)

+import re
+
+RULES_FOR_FILTRATION = {"EMAIL": "[EMAIL]",
+ "PHONE": "[PHONE]",
+ "PARTIAL": "[FILTERED]"}
+
+HOSTNAME_PATTERN = "(?P<hostname>([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+" + \
+ "[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)"
+
+EMAIL_USERNAME_PATTERN = "(?P<username>[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{0,200})"
+EMAIL_PATTERN = EMAIL_USERNAME_PATTERN + "[@]" + HOSTNAME_PATTERN
+
+PHONE_SEPARATOR = "[\s\(\)-]"
+PHONE_CODE_PATTERN = "((?P<code>(00|\+)[1-9][0-9]{0,2})|0)"
+PHONE_BASE_PATTERN = "" + \
+ "(?(code)" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?|" + \
+ "(" + PHONE_SEPARATOR + "?[1-9]" + PHONE_SEPARATOR + "?|" + \
+ PHONE_SEPARATOR + "[0-9]" + PHONE_SEPARATOR + "?))" + \
+ "(" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?){4,9}" + \
+ PHONE_SEPARATOR + "?[0-9]"
+
+PHONE_PATTERN = "(" + PHONE_CODE_PATTERN + PHONE_BASE_PATTERN + ")"
+
+IP_ADDRESS_PATTERN = "((\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))" + \
+ "(\.(\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))){3})"
+
+NUMBER_PATTERN = "([-]?(0|[1-9]\d*)(\.\d+)?)"
+INTEGER_PATTERN = "([-]?(0|[1-9]\d*))"
+DATE_PATTERN = "(\d{4}[-](0\d|1[0-2])[-]([0-2]\d|3[0-1]))"
+TIME_PATTERN = "(([0-1]\d|2[0-3])([:][0-5]\d){2})"
+DATETIME_PATTERN = DATE_PATTERN + "[\s:T-]" + TIME_PATTERN
+
+
+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):
+
+ text = self.text[:]
+
+ text = self.__filter_email(text)
+
+ text = self.__filter_phone(text)
+
+ return text
+
+ def __filter_email(self, text):
+
+ if self.partially_preserve_email_username:
+ return re.sub(EMAIL_PATTERN,
+ lambda match:
+ RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ + match.group("hostname")
+ if len(match.group("username")) < 6
+ else match.group("username")[0:3] +
+ RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ + match.group("hostname"),
+ text)
+ if self.preserve_email_hostname:
+ return re.sub(EMAIL_PATTERN,
+ RULES_FOR_FILTRATION['PARTIAL'] + r"@\g<hostname>",
+ text)
+ if not(self.preserve_email_hostname
+ or self.partially_preserve_email_username):
+ return re.sub(
+ EMAIL_PATTERN, RULES_FOR_FILTRATION['EMAIL'], text)
+
+ def __filter_phone(self, text):
+
+ if self.preserve_phone_country_code:
+ return re.sub("(?<=[\s\(\)-])" + PHONE_PATTERN,
+ lambda match:
+ RULES_FOR_FILTRATION["PHONE"]
+ if match.group("code") is None
+ else match.group("code") + " "
+ + RULES_FOR_FILTRATION['PARTIAL'],
+ text)
+ else:
+ return re.sub(
+ "(?<=[\s\(\)-])" + PHONE_PATTERN, RULES_FOR_FILTRATION['PHONE'], text)
+
+
+class Validations:
+ #
+
+ @classmethod
+ def is_email(cls, value):
+ if re.search("^" + EMAIL_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_phone(cls, value):
+ if re.search("^" + PHONE_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_hostname(cls, value):
+ if re.search("^" + HOSTNAME_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_ip_address(cls, value):
+ if re.search("^" + IP_ADDRESS_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_number(cls, value):
+ if re.search("^" + NUMBER_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_integer(cls, value):
+ if re.search("^" + INTEGER_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_date(cls, value):
+ if re.search("^" + DATE_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_time(cls, value):
+ if re.search("^" + TIME_PATTERN + "$", value) is None:
+ return False
+ return True
+
+ @classmethod
+ def is_datetime(cls, value):
+ if re.search("^" + DATETIME_PATTERN + "$", value) is None:
+ return False
+ return True

Димитър обнови решението на 23.04.2014 01:14 (преди над 10 години)

import re
RULES_FOR_FILTRATION = {"EMAIL": "[EMAIL]",
"PHONE": "[PHONE]",
"PARTIAL": "[FILTERED]"}
HOSTNAME_PATTERN = "(?P<hostname>([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+" + \
"[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)"
EMAIL_USERNAME_PATTERN = "(?P<username>[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{0,200})"
EMAIL_PATTERN = EMAIL_USERNAME_PATTERN + "[@]" + HOSTNAME_PATTERN
PHONE_SEPARATOR = "[\s\(\)-]"
PHONE_CODE_PATTERN = "((?P<code>(00|\+)[1-9][0-9]{0,2})|0)"
PHONE_BASE_PATTERN = "" + \
"(?(code)" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?|" + \
"(" + PHONE_SEPARATOR + "?[1-9]" + PHONE_SEPARATOR + "?|" + \
PHONE_SEPARATOR + "[0-9]" + PHONE_SEPARATOR + "?))" + \
"(" + PHONE_SEPARATOR + "?[0-9]" + PHONE_SEPARATOR + "?){4,9}" + \
PHONE_SEPARATOR + "?[0-9]"
PHONE_PATTERN = "(" + PHONE_CODE_PATTERN + PHONE_BASE_PATTERN + ")"
IP_ADDRESS_PATTERN = "((\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))" + \
"(\.(\d|[1-9]\d|1\d{2}|2([0-4][0-9]|5[0-5]))){3})"
NUMBER_PATTERN = "([-]?(0|[1-9]\d*)(\.\d+)?)"
INTEGER_PATTERN = "([-]?(0|[1-9]\d*))"
DATE_PATTERN = "(\d{4}[-](0\d|1[0-2])[-]([0-2]\d|3[0-1]))"
TIME_PATTERN = "(([0-1]\d|2[0-3])([:][0-5]\d){2})"
DATETIME_PATTERN = DATE_PATTERN + "[\s:T-]" + TIME_PATTERN
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):
text = self.text[:]
text = self.__filter_email(text)
text = self.__filter_phone(text)
return text
def __filter_email(self, text):
if self.partially_preserve_email_username:
return re.sub(EMAIL_PATTERN,
lambda match:
RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ match.group("hostname")
if len(match.group("username")) < 6
else match.group("username")[0:3] +
RULES_FOR_FILTRATION['PARTIAL'] + "@"
+ match.group("hostname"),
text)
if self.preserve_email_hostname:
return re.sub(EMAIL_PATTERN,
RULES_FOR_FILTRATION['PARTIAL'] + r"@\g<hostname>",
text)
if not(self.preserve_email_hostname
or self.partially_preserve_email_username):
return re.sub(
EMAIL_PATTERN, RULES_FOR_FILTRATION['EMAIL'], text)
def __filter_phone(self, text):
if self.preserve_phone_country_code:
- return re.sub("(?<=[\s\(\)-])" + PHONE_PATTERN,
+ return re.sub("((?<=[\s\(\)-])|^)" + PHONE_PATTERN,
lambda match:
RULES_FOR_FILTRATION["PHONE"]
if match.group("code") is None
else match.group("code") + " "
+ RULES_FOR_FILTRATION['PARTIAL'],
text)
else:
return re.sub(
- "(?<=[\s\(\)-])" + PHONE_PATTERN, RULES_FOR_FILTRATION['PHONE'], text)
+ "((?<=[\s\(\)-])|^)" + PHONE_PATTERN, RULES_FOR_FILTRATION['PHONE'], text)
class Validations:
#
@classmethod
def is_email(cls, value):
if re.search("^" + EMAIL_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_phone(cls, value):
if re.search("^" + PHONE_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_hostname(cls, value):
if re.search("^" + HOSTNAME_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_ip_address(cls, value):
if re.search("^" + IP_ADDRESS_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_number(cls, value):
if re.search("^" + NUMBER_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_integer(cls, value):
if re.search("^" + INTEGER_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_date(cls, value):
if re.search("^" + DATE_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_time(cls, value):
if re.search("^" + TIME_PATTERN + "$", value) is None:
return False
return True
@classmethod
def is_datetime(cls, value):
if re.search("^" + DATETIME_PATTERN + "$", value) is None:
return False
return True