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

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

Към профила на Деян Камбуров

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 31 успешни тест(а)
  • 8 неуспешни тест(а)

Код

import re
class PrivacyFilter:
preserve_email_hostname = False
partially_preserve_email_username = False
preserve_phone_country_code = False
def __init__(self, text):
self._text = text
def filtered(self):
def make_replace_pattern(matchObj):
if self.partially_preserve_email_username:
if len(matchObj.group(1)) < 6:
return "[FILTERED]" + matchObj.group(2)
else:
return (matchObj.group(1)[0:3] +
"[FILTERED]" +
matchObj.group(2))
elif self.preserve_email_hostname:
return "[FILTERED]" + matchObj.group(2)
else:
return "[EMAIL]"
domain_name = "[0-9a-zA-Z]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?"
filtered_text = re.sub(r"\b([0-9a-zA-Z][\w\.\\+-]{0,200})(\@"
r"(" + domain_name + "\.)*" +
domain_name +
r"(\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?))\b",
make_replace_pattern,
self._text)
phone_international = (r"((\b00|\+)[1-9]\d{0,2})"
r"([ \(\)-]?\d[ \(\)-]?){5,10}([ \(\)-]?\d)\b")
phone_local = (r"\b0[ \(\)-]{0,2}[1-9][ \(\)-]?"
r"([ \(\)-]?\d[ \(\)-]?){4,9}([ \(\)-]?\d)\b")
replacement = r"[PHONE]"
if self.preserve_phone_country_code:
replacement = r"\1 [FILTERED]"
filtered_text = re.sub(phone_international, replacement, filtered_text)
return re.sub(phone_local, r"[PHONE]", filtered_text)
class Validations:
@classmethod
def is_email(cls, value):
match = re.search(r"^[0-9a-zA-Z][\w\.\\+-]{0,200}\@(.*)$", value)
if match is None:
return False
return cls.is_hostname(match.group(1))
@classmethod
def is_phone(cls, value):
phone_international = (r"^((00|\+)[1-9]\d{0,2})"
r"([ \(\)-]?\d[ \(\)-]?){5,10}([ \(\)-]?\d)$")
phone_local = (r"^0[ \(\)-]{0,2}[1-9][ \(\)-]?"
r"([ \(\)-]?\d[ \(\)-]?){4,9}([ \(\)-]?\d)$")
return (cls.__is_matching(phone_international, value) or
cls.__is_matching(phone_local, value))
@classmethod
def is_hostname(cls, value):
domain_name = r"[0-9a-zA-Z]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?"
return cls.__is_matching(r"^(" + domain_name + "\.)*" +
domain_name +
"(\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)$", value)
@classmethod
def is_ip_address(cls, value):
group = "(0|[1-9]\d*)"
match = re.search(r"^" + (group + "\.") * 3 + group + "$", value)
if match is None:
return False
for index in range(1, 5):
byte = int(match.group(index))
if not 0 <= byte <= 255:
return False
return True
@classmethod
def is_number(cls, value):
return cls.__is_matching(r"^-?(0|[1-9]\d*)(\.\d+)?$", value)
@classmethod
def is_integer(cls, value):
return cls.__is_matching(r"^-?(0|[1-9]\d*)$", value)
@classmethod
def is_date(cls, value):
match = re.search(r"^\d{4}-(\d\d)-(\d\d)$", value)
if match is None:
return False
month = int(match.group(1))
day = int(match.group(2))
return 1 <= month <= 12 and 1 <= day <= 31
@classmethod
def is_time(cls, value):
match = re.search(r"^(\d\d):(\d\d):(\d\d)$", value)
if match is None:
return False
hours = int(match.group(1))
minutes = int(match.group(2))
seconds = int(match.group(3))
return 0 <= hours <= 23 and 0 <= minutes <= 59 and 0 <= seconds <= 59
@classmethod
def is_datetime(cls, value):
match = re.search(r"(\d{4}-\d\d-\d\d)( |T)(\d\d:\d\d:\d\d)", value)
if match is None:
return False
return cls.is_date(match.group(1)) and cls.is_time(match.group(3))
def __is_matching(pattern, value):
match = re.search(pattern, value)
if match is None:
return False
return True

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

....FF....F.....F.....FF..FF...........
======================================================================
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-dnihce/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-dnihce/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_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-dnihce/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-dnihce/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_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-dnihce/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-dnihce/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-dnihce/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-dnihce/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

----------------------------------------------------------------------
Ran 39 tests in 0.050s

FAILED (failures=8)

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

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

+import re
+
+
+class PrivacyFilter:
+ preserve_email_hostname = False
+ partially_preserve_email_username = False
+ preserve_phone_country_code = False
+
+ def __init__(self, text):
+ self._text = text
+
+ def filtered(self):
+ def make_replace_pattern(matchObj):
+ if self.partially_preserve_email_username:
+ if len(matchObj.group(1)) < 6:
+ return "[FILTERED]" + matchObj.group(2)
+ else:
+ return (matchObj.group(1)[0:3] +
+ "[FILTERED]" +
+ matchObj.group(2))
+ elif self.preserve_email_hostname:
+ return "[FILTERED]" + matchObj.group(2)
+ else:
+ return "[EMAIL]"
+ domain_name = "[0-9a-zA-Z]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?"
+ filtered_text = re.sub(r"\b([0-9a-zA-Z][\w\.\\+-]{0,200})(\@"
+ r"(" + domain_name + "\.)*" +
+ domain_name +
+ r"(\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?))\b",
+ make_replace_pattern,
+ self._text)
+ phone_international = (r"((\b00|\+)[1-9]\d{0,2})"
+ r"([ \(\)-]?\d[ \(\)-]?){5,10}([ \(\)-]?\d)\b")
+ phone_local = (r"\b0[ \(\)-]{0,2}[1-9][ \(\)-]?"
+ r"([ \(\)-]?\d[ \(\)-]?){4,9}([ \(\)-]?\d)\b")
+ replacement = r"[PHONE]"
+ if self.preserve_phone_country_code:
+ replacement = r"\1 [FILTERED]"
+ filtered_text = re.sub(phone_international, replacement, filtered_text)
+ return re.sub(phone_local, r"[PHONE]", filtered_text)
+
+
+class Validations:
+ @classmethod
+ def is_email(cls, value):
+ match = re.search(r"^[0-9a-zA-Z][\w\.\\+-]{0,200}\@(.*)$", value)
+ if match is None:
+ return False
+ return cls.is_hostname(match.group(1))
+
+ @classmethod
+ def is_phone(cls, value):
+ phone_international = (r"^((00|\+)[1-9]\d{0,2})"
+ r"([ \(\)-]?\d[ \(\)-]?){5,10}([ \(\)-]?\d)$")
+ phone_local = (r"^0[ \(\)-]{0,2}[1-9][ \(\)-]?"
+ r"([ \(\)-]?\d[ \(\)-]?){4,9}([ \(\)-]?\d)$")
+ return (cls.__is_matching(phone_international, value) or
+ cls.__is_matching(phone_local, value))
+
+ @classmethod
+ def is_hostname(cls, value):
+ domain_name = r"[0-9a-zA-Z]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?"
+ return cls.__is_matching(r"^(" + domain_name + "\.)*" +
+ domain_name +
+ "(\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)$", value)
+
+ @classmethod
+ def is_ip_address(cls, value):
+ group = "(0|[1-9]\d*)"
+ match = re.search(r"^" + (group + "\.") * 3 + group + "$", value)
+ if match is None:
+ return False
+ for index in range(1, 5):
+ byte = int(match.group(index))
+ if not 0 <= byte <= 255:
+ return False
+ return True
+
+ @classmethod
+ def is_number(cls, value):
+ return cls.__is_matching(r"^-?(0|[1-9]\d*)(\.\d+)?$", value)
+
+ @classmethod
+ def is_integer(cls, value):
+ return cls.__is_matching(r"^-?(0|[1-9]\d*)$", value)
+
+ @classmethod
+ def is_date(cls, value):
+ match = re.search(r"^\d{4}-(\d\d)-(\d\d)$", value)
+ if match is None:
+ return False
+ month = int(match.group(1))
+ day = int(match.group(2))
+ return 1 <= month <= 12 and 1 <= day <= 31
+
+ @classmethod
+ def is_time(cls, value):
+ match = re.search(r"^(\d\d):(\d\d):(\d\d)$", value)
+ if match is None:
+ return False
+ hours = int(match.group(1))
+ minutes = int(match.group(2))
+ seconds = int(match.group(3))
+ return 0 <= hours <= 23 and 0 <= minutes <= 59 and 0 <= seconds <= 59
+
+ @classmethod
+ def is_datetime(cls, value):
+ match = re.search(r"(\d{4}-\d\d-\d\d)( |T)(\d\d:\d\d:\d\d)", value)
+ if match is None:
+ return False
+ return cls.is_date(match.group(1)) and cls.is_time(match.group(3))
+
+ def __is_matching(pattern, value):
+ match = re.search(pattern, value)
+ if match is None:
+ return False
+ return True