Решение на Регулярни изрази от Тихомир Кожухарски

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

Към профила на Тихомир Кожухарски

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 19 успешни тест(а)
  • 20 неуспешни тест(а)

Код

import re
Constants = {
'patterns': {
'email_partially_preserve_username':
r'(([A-Za-z\d][-\w+.]{2})[-\w+.]{3,198})@(([\dA-Za-z]([-\dA-Za-z]{'
+ r'0,61}[\dA-Za-z])?\.)*([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?'
+ r')\.([A-Za-z]{2,3}))',
'email':
r'([A-Za-z\d][-\w+.]{0,200})@(([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za'
+ r'-z])?\.)*([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?)\.([A-Za-z]'
+ r'{2,3}))',
'hostname':
r'([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?\.)*([\dA-Za-z]([-\dA-Z'
+ r'a-z]{0,61}[\dA-Za-z])?)\.([A-Za-z]{2,3})',
'internationalPhoneCodes':
r'93|355|213|1684|376|244|1264|672|1268|54|374|297|61|43|994|1242|'
+ r'973|880|1246|375|32|501|229|1441|975|591|387|267|55|1284|673|3'
+ r'59|226|95|257|855|237|1|238|1345|236|235|56|86|61|61|57|269|24'
+ r'2|243|682|506|385|53|357|420|45|253|1767|1809|670|593|20|503|2'
+ r'40|291|372|251|500|298|679|358|33|689|241|220|970|995|49|233|3'
+ r'50|30|299|1473|1671|502|224|245|592|509|504|852|36|354|91|62|9'
+ r'8|964|353|44|972|39|225|1876|81|962|7|254|686|381|965|996|856|'
+ r'371|961|266|231|218|423|370|352|853|389|261|265|60|960|223|356'
+ r'|692|222|230|262|52|691|373|377|976|382|1664|212|258|264|674|9'
+ r'77|31|599|687|64|505|227|234|683|672|1670|850|47|968|92|680|50'
+ r'7|675|595|51|63|870|48|351|1|974|40|7|250|590|685|378|239|966|'
+ r'221|381|248|232|65|421|386|677|252|27|82|34|94|290|1869|1758|1'
+ r'599|508|1784|249|597|268|46|41|963|886|992|255|66|228|690|676|'
+ r'1868|216|90|993|1649|688|971|256|44|380|598|1|998|678|39|58|84'
+ r'|1340|681|970|967|260|263',
'phone':
r'((?<![\da-zA-Z+])0(?!0)|(\b00|\+)(__INTERNATIONAL_CODES__))([- ('
+ r')]{0,2}\d){6,11}',
'ip':
r'((\d|[1-9]\d|1\d{2}|2([0-4]\d|5[0-5]))\.){3}(\d|[1-9]\d|1\d{2}|2'
+ r'([0-4]\d|5[0-5]))',
'number': r'-?(0|[1-9]\d*)(\.\d+)?',
'integer': r'-?(0|[1-9]\d*)',
'date': r'\d{4}-(0\d|1[0-2])-([0-2]\d|3[01])',
'time': r'\d{2}:\d{2}:\d{2}',
'datetime': r'\d{4}-(0\d|1[0-2])-([0-2]\d|3[01])[ T]\d{2}:\d{2}:\d{2}'
}
}
Constants['patterns']['phone'] = re.sub(
'__INTERNATIONAL_CODES__',
Constants['patterns']['internationalPhoneCodes'],
Constants['patterns']['phone']
)
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 filter(self, text):
filtered_text = text
if self.partially_preserve_email_username:
filtered_text = re.sub(
Constants['patterns']['email_partially_preserve_username'],
r'\2[FILTERED]@\3',
filtered_text
)
filtered_text = re.sub(
Constants['patterns']['email'], r'[FILTERED]@\2',
filtered_text
)
elif self.preserve_email_hostname:
filtered_text = re.sub(
Constants['patterns']['email'], r'[FILTERED]@\2',
filtered_text
)
else:
filtered_text = re.sub(
Constants['patterns']['email'], r'[EMAIL]', filtered_text
)
if self.preserve_phone_country_code:
filtered_text = re.sub(
Constants['patterns']['phone'], r'\1 [FILTERED]', filtered_text
)
else:
filtered_text = re.sub(
Constants['patterns']['phone'], r'[PHONE]', filtered_text
)
return filtered_text
def filtered(self):
return self.filter(self.text)
class Validations:
@classmethod
def is_email(cls, value):
return bool(re.search(Constants['patterns']['email'], value))
@classmethod
def is_phone(cls, value):
return bool(re.search(Constants['patterns']['phone'], value))
@classmethod
def is_hostname(cls, value):
return bool(re.search(Constants['patterns']['hostname'], value))
@classmethod
def is_ip_address(cls, value):
return bool(re.search(Constants['patterns']['ip'], value))
@classmethod
def is_number(cls, value):
return bool(re.search(Constants['patterns']['number'], value))
@classmethod
def is_integer(cls, value):
return bool(re.search(Constants['patterns']['integer'], value))
@classmethod
def is_date(cls, value):
return bool(re.search(Constants['patterns']['date'], value))
@classmethod
def is_time(cls, value):
return bool(re.search(Constants['patterns']['time'], value))
@classmethod
def is_datetime(cls, value):
return bool(re.search(Constants['patterns']['datetime'], value))

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

...FF.....F....FFF.FFFFFFFFF.F.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-sgw4ke/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-sgw4ke/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_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-sgw4ke/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: +25( 55 )12 12255'
- Phone: +25 [FILTERED]
+ Phone: +25( 55 )12 12255


======================================================================
FAIL: test_can_validate_more_complex_emails (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-sgw4ke/test.py", line 124, in test_can_validate_more_complex_emails
    self.assertIs(solution.Validations.is_email(email), valid)
AssertionError: True is not False

======================================================================
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-sgw4ke/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_invalid_hours_minutes_or_seconds (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-sgw4ke/test.py", line 270, in test_does_not_allow_invalid_hours_minutes_or_seconds
    self.assertFalse(solution.Validations.is_time('24:00:00'))
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-sgw4ke/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_does_not_break_on_emails_in_multiline_strings (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-sgw4ke/test.py", line 127, in test_does_not_break_on_emails_in_multiline_strings
    self.assertFalse(solution.Validations.is_email("foo@bar.com\nwat?"))
AssertionError: True is not false

======================================================================
FAIL: test_does_not_break_on_phones_in_multiline_strings (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-sgw4ke/test.py", line 163, in test_does_not_break_on_phones_in_multiline_strings
    self.assertFalse(solution.Validations.is_phone("0885123123\nwat?"))
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-sgw4ke/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-sgw4ke/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_multiline_strings_in_integer_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-sgw4ke/test.py", line 233, in test_handles_multiline_strings_in_integer_validation_properly
    self.assertFalse(solution.Validations.is_number("42\n24"))
AssertionError: True is not false

======================================================================
FAIL: test_handles_multiline_strings_in_numbers_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-sgw4ke/test.py", line 215, in test_handles_multiline_strings_in_numbers_validation_properly
    self.assertFalse(solution.Validations.is_number("42\n24"))
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-sgw4ke/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-sgw4ke/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_IP_addresses (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-sgw4ke/test.py", line 184, in test_validates_IP_addresses
    self.assertFalse(solution.Validations.is_ip_address('300.2.3.4'))
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-sgw4ke/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-sgw4ke/test.py", line 176, in test_validates_hostnames
    self.assertFalse(solution.Validations.is_hostname('not-a-hostname.com.12'))
AssertionError: True is not false

======================================================================
FAIL: test_validates_more_complex_integers (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-sgw4ke/test.py", line 223, in test_validates_more_complex_integers
    self.assertFalse(solution.Validations.is_integer(' 42 '))
AssertionError: True is not false

======================================================================
FAIL: test_validates_more_complex_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-sgw4ke/test.py", line 200, in test_validates_more_complex_numbers
    self.assertFalse(solution.Validations.is_number(' 42 '))
AssertionError: True is not false

----------------------------------------------------------------------
Ran 39 tests in 0.065s

FAILED (failures=20)

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

Тихомир обнови решението на 21.04.2014 20:33 (преди над 10 години)

+import re
+
+Constants = {
+ 'patterns': {
+ 'email_partially_preserve_username':
+ r'(([A-Za-z\d][-\w+.]{2})[-\w+.]{3,198})@(([\dA-Za-z]([-\dA-Za-z]{'
+ + r'0,61}[\dA-Za-z])?\.)*([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?'
+ + r')\.([A-Za-z]{2,3}))',
+
+ 'email':
+ r'([A-Za-z\d][-\w+.]{0,200})@(([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za'
+ + r'-z])?\.)*([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?)\.([A-Za-z]'
+ + r'{2,3}))',
+
+ 'hostname':
+ r'([\dA-Za-z]([-\dA-Za-z]{0,61}[\dA-Za-z])?\.)*([\dA-Za-z]([-\dA-Z'
+ + r'a-z]{0,61}[\dA-Za-z])?)\.([A-Za-z]{2,3})',
+
+ 'internationalPhoneCodes':
+ r'93|355|213|1684|376|244|1264|672|1268|54|374|297|61|43|994|1242|'
+ + r'973|880|1246|375|32|501|229|1441|975|591|387|267|55|1284|673|3'
+ + r'59|226|95|257|855|237|1|238|1345|236|235|56|86|61|61|57|269|24'
+ + r'2|243|682|506|385|53|357|420|45|253|1767|1809|670|593|20|503|2'
+ + r'40|291|372|251|500|298|679|358|33|689|241|220|970|995|49|233|3'
+ + r'50|30|299|1473|1671|502|224|245|592|509|504|852|36|354|91|62|9'
+ + r'8|964|353|44|972|39|225|1876|81|962|7|254|686|381|965|996|856|'
+ + r'371|961|266|231|218|423|370|352|853|389|261|265|60|960|223|356'
+ + r'|692|222|230|262|52|691|373|377|976|382|1664|212|258|264|674|9'
+ + r'77|31|599|687|64|505|227|234|683|672|1670|850|47|968|92|680|50'
+ + r'7|675|595|51|63|870|48|351|1|974|40|7|250|590|685|378|239|966|'
+ + r'221|381|248|232|65|421|386|677|252|27|82|34|94|290|1869|1758|1'
+ + r'599|508|1784|249|597|268|46|41|963|886|992|255|66|228|690|676|'
+ + r'1868|216|90|993|1649|688|971|256|44|380|598|1|998|678|39|58|84'
+ + r'|1340|681|970|967|260|263',
+
+ 'phone':
+ r'((?<![\da-zA-Z+])0(?!0)|(\b00|\+)(__INTERNATIONAL_CODES__))([- ('
+ + r')]{0,2}\d){6,11}',
+
+ 'ip':
+ r'((\d|[1-9]\d|1\d{2}|2([0-4]\d|5[0-5]))\.){3}(\d|[1-9]\d|1\d{2}|2'
+ + r'([0-4]\d|5[0-5]))',
+
+ 'number': r'-?(0|[1-9]\d*)(\.\d+)?',
+ 'integer': r'-?(0|[1-9]\d*)',
+ 'date': r'\d{4}-(0\d|1[0-2])-([0-2]\d|3[01])',
+ 'time': r'\d{2}:\d{2}:\d{2}',
+ 'datetime': r'\d{4}-(0\d|1[0-2])-([0-2]\d|3[01])[ T]\d{2}:\d{2}:\d{2}'
+ }
+}
+
+Constants['patterns']['phone'] = re.sub(
+ '__INTERNATIONAL_CODES__',
+ Constants['patterns']['internationalPhoneCodes'],
+ Constants['patterns']['phone']
+)
+
+
+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 filter(self, text):
+
+ filtered_text = text
+ if self.partially_preserve_email_username:
+ filtered_text = re.sub(
+ Constants['patterns']['email_partially_preserve_username'],
+ r'\2[FILTERED]@\3',
+ filtered_text
+ )
+ filtered_text = re.sub(
+ Constants['patterns']['email'], r'[FILTERED]@\2',
+ filtered_text
+ )
+
+ elif self.preserve_email_hostname:
+ filtered_text = re.sub(
+ Constants['patterns']['email'], r'[FILTERED]@\2',
+ filtered_text
+ )
+ else:
+ filtered_text = re.sub(
+ Constants['patterns']['email'], r'[EMAIL]', filtered_text
+ )
+
+ if self.preserve_phone_country_code:
+ filtered_text = re.sub(
+ Constants['patterns']['phone'], r'\1 [FILTERED]', filtered_text
+ )
+ else:
+ filtered_text = re.sub(
+ Constants['patterns']['phone'], r'[PHONE]', filtered_text
+ )
+
+ return filtered_text
+
+ def filtered(self):
+ return self.filter(self.text)
+
+
+class Validations:
+ @classmethod
+ def is_email(cls, value):
+ return bool(re.search(Constants['patterns']['email'], value))
+
+ @classmethod
+ def is_phone(cls, value):
+ return bool(re.search(Constants['patterns']['phone'], value))
+
+ @classmethod
+ def is_hostname(cls, value):
+ return bool(re.search(Constants['patterns']['hostname'], value))
+
+ @classmethod
+ def is_ip_address(cls, value):
+ return bool(re.search(Constants['patterns']['ip'], value))
+
+ @classmethod
+ def is_number(cls, value):
+ return bool(re.search(Constants['patterns']['number'], value))
+
+ @classmethod
+ def is_integer(cls, value):
+ return bool(re.search(Constants['patterns']['integer'], value))
+
+ @classmethod
+ def is_date(cls, value):
+ return bool(re.search(Constants['patterns']['date'], value))
+
+ @classmethod
+ def is_time(cls, value):
+ return bool(re.search(Constants['patterns']['time'], value))
+
+ @classmethod
+ def is_datetime(cls, value):
+ return bool(re.search(Constants['patterns']['datetime'], value))