Решение на Регулярни изрази от Стефани Цакова

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

Към профила на Стефани Цакова

Резултати

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

Код

import re
VALID_MAIL = r'\b[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@[a-zA-Z0-9]'\
r'[a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?\b'
VALID_MAIL_PREFIX = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@'
VALID_HOST = '@([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)'\
'+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
VALID_LOCAL_PHONE = r'\b0[-\s\(\)]{,2}[1-9]([-\s\(\)]{,2}\d){6,10}\d?\b'
INTERNATIONAL_PHONE = r"(\B\+|\b00)[1-9]\d{,2}([-\s\(\)]{,2}\d){6,10}\d?\b"
IP = '^(\d\.|[1-9]\d\.|1\d\d\.|2[0-5][0-5]\.){3}'\
'(\d|[1-9]\d|1\d\d|2[0-5][0-5])\Z'
class Validations:
@classmethod
def is_phone(self, value):
inner = '([-\s\(\)]{,2}\d){6,10}\d?\Z'
local = "^0[-\s\(\)]{,2}[1-9]" + inner
international = "^(00|\+)[1-9]\d{,2}" + inner
return bool(re.match(international, value))\
or bool(re.match(local, value))
@classmethod
def is_hostname(self, value):
return bool(re.match('^' + VALID_HOST[1:] + '\Z', value))
@classmethod
def is_email(self, value):
return bool(re.match(VALID_MAIL_PREFIX, value)) and \
self.is_hostname(value.split('@', 1)[1])
@classmethod
def is_ip_address(self, value):
return bool(re.match(IP, value))
@classmethod
def is_integer(self, value):
return bool(re.match('^-?(0|[1-9][0-9]*)\Z', value))
@classmethod
def is_number(self, value):
return bool(re.match('^-?(0[1-9]*|[1-9][0-9]*).?[0-9]*\Z', value))
@classmethod
def is_date(self, value):
return bool(re.match(
'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\d|3[0-1])\Z',
value))
@classmethod
def is_time(self, value):
return bool(re.match('^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\Z', value))
@classmethod
def is_datetime(self, value):
split_T = value.split('T', 1)
split_S = value.split(' ', 1)
return self.is_date(split_T[0]) and self.is_time(split_T[1]) or \
self.is_date(split_S[0]) and self.is_time(split_S[1])
class PrivacyFilter:
preserve_phone_country_code = False
preserve_email_hostname = False
partially_preserve_email_username = False
def __init__(self, value):
self.value = value
def filtered(self):
working_copy = self.value
while re.search(VALID_MAIL, working_copy):
mail = re.search(VALID_MAIL, working_copy).group()
host = re.search(VALID_HOST, mail).group()
prefix = re.search(
'[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,2}', mail).group()
length = len(re.search(VALID_MAIL_PREFIX, mail).group()) - 1
if self.partially_preserve_email_username and length < 6:
target = '[FILTERED]' + host
elif self.partially_preserve_email_username:
target = prefix + '[FILTERED]' + host
elif self.preserve_email_hostname:
target = '[FILTERED]' + host
else:
target = '[EMAIL]'
working_copy = working_copy.replace(mail, target)
while re.search(VALID_LOCAL_PHONE, working_copy) or \
re.search(INTERNATIONAL_PHONE, working_copy):
local_phone = re.search(VALID_LOCAL_PHONE, working_copy)
international_phone = re.search(
INTERNATIONAL_PHONE, working_copy)
if not self.preserve_phone_country_code and international_phone:
working_copy = working_copy.replace(
international_phone.group(), '[PHONE]')
elif self.preserve_phone_country_code and international_phone:
prefix = re.search(
'(00|\+)[1-9]\d{,2}', international_phone.group())
target = prefix.group() + " [FILTERED]"
working_copy = working_copy.replace(
international_phone.group(), target)
elif local_phone:
working_copy = working_copy.replace(
local_phone.group(), '[PHONE]')
return working_copy

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

F...F..F........................F..F...
======================================================================
FAIL: test_allows_email_hostname_to_be_preserved (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-1ymo95y/test.py", line 55, in test_allows_email_hostname_to_be_preserved
    self.assertEqual('[FILTERED]@exa.mple.com', self.filter_email_usernames('some12-+3@exa.mple.com'))
AssertionError: '[FILTERED]@exa.mple.com' != 'some12-+3@exa.mple.com'
- [FILTERED]@exa.mple.com
+ some12-+3@exa.mple.com


======================================================================
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-1ymo95y/test.py", line 86, in test_does_not_filter_invalid_phone_numbers
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: '+1555 123, 55555' != '[PHONE], 55555'
- +1555 123, 55555
+ [PHONE], 55555


======================================================================
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-1ymo95y/test.py", line 37, in test_obfuscates_more_complicated_emails
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: 'Contact: [EMAIL],[EMAIL]' != 'Contact: [EMAIL],someone.new@sub.example123.co.uk'
- Contact: [EMAIL],[EMAIL]
+ Contact: [EMAIL],someone.new@sub.example123.co.uk


======================================================================
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-1ymo95y/test.py", line 174, in test_validates_hostnames
    self.assertFalse(solution.Validations.is_hostname('not-a-hostname-.com'))
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-1ymo95y/test.py", line 205, in test_validates_more_complex_numbers
    self.assertFalse(solution.Validations.is_number('00'))
AssertionError: True is not false

----------------------------------------------------------------------
Ran 39 tests in 0.060s

FAILED (failures=5)

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

Стефани обнови решението на 18.04.2014 16:08 (преди около 10 години)

+import re
+VALID_MAIL = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?'
+VALID_MAIL_PREFIX = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@'
+VALID_HOST = '@[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?'
+VALID_LOCAL_PHONE = '0[-\s\(\)]{,2}[1-9]([-\s\(\)]{,2}\d){6,10}\d?'
+VALID_INTERNATIONAL_PHONE = '(00|\+)[1-9]\d{,2}([-\s\(\)]{,2}\d){6,10}\d?'
+IP = '^(\d\.|[1-9]\d\.|1\d\d\.|2[0-5][0-6]\.){3}(\d|[1-9]\d|1\d\d|2[0-5][0-6])\Z'
+
+
+class Validations:
+
+ @classmethod
+ def is_phone(self, value):
+ inner = '([-\s\(\)]{,2}\d){6,10}\d?\Z'
+ local = "^0[-\s\(\)]{,2}[1-9]" + inner
+ international = "^(00|\+)[1-9]\d{,2}" + inner
+ return bool(re.match(international, value))\
+ or bool(re.match(local, value))
+
+ @classmethod
+ def is_hostname(self, value):
+ return bool(re.match('^[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?\Z', value))
+
+ @classmethod
+ def is_email(self, value):
+ return bool(re.match(VALID_MAIL_PREFIX, value)) and \
+ self.is_hostname(value.split('@', 1)[1])
+
+ @classmethod
+ def is_ip_address(self, value):
+ return bool(re.match(IP, value))
+
+ @classmethod
+ def is_integer(self, value):
+ return bool(re.match('^-?(0|[1-9][0-9]*)\Z', value))
+
+ @classmethod
+ def is_number(self, value):
+ return bool(re.match('^-?(0[1-9]*|[1-9][0-9]*).?[0-9]*\Z', value))
+
+ @classmethod
+ def is_date(self, value):
+ return bool(re.match(
+ '^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\d|3[0-1])\Z',
+ value))
+
+ @classmethod
+ def is_time(self, value):
+ return bool(re.match('^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\Z', value))
+
+ @classmethod
+ def is_datetime(self, value):
+ split_T = value.split('T', 1)
+ split_S = value.split(' ', 1)
+ return self.is_date(split_T[0]) and self.is_time(split_T[1]) or \
+ self.is_date(split_S[0]) and self.is_time(split_S[1])
+
+
+class PrivacyFilter:
+
+ preserve_phone_country_code = False
+ preserve_email_hostname = False
+ partially_preserve_email_username = False
+
+ def __init__(self, value):
+ self.value = value
+
+ def filtered(self):
+ working_copy = self.value
+
+ while re.search(VALID_MAIL, working_copy):
+ mail = re.search(VALID_MAIL, working_copy).group()
+ host = re.search(VALID_HOST, mail).group()
+ prefix = re.search(
+ '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,2}', mail).group()
+ length = len(re.search(VALID_MAIL_PREFIX, mail).group())
+ if self.partially_preserve_email_username and length < 6:
+ target = '[FILTERED]' + host
+ elif self.partially_preserve_email_username:
+ target = prefix + '[FILTERED]' + host
+ elif self.preserve_email_hostname:
+ target = '[FILTERED]' + host
+ else:
+ target = '[EMAIL]'
+ working_copy = working_copy.replace(mail, target)
+
+ while re.search(VALID_LOCAL_PHONE, working_copy) or \
+ re.search(VALID_INTERNATIONAL_PHONE, working_copy):
+ local_phone = re.search(VALID_LOCAL_PHONE, working_copy)
+ international_phone = re.search(
+ VALID_INTERNATIONAL_PHONE, working_copy)
+ if local_phone:
+ working_copy = working_copy.replace(
+ local_phone.group(), '[PHONE]')
+ elif not self.preserve_phone_country_code and international_phone:
+ working_copy = working_copy.replace(
+ international_phone.group(), '[PHONE]')
+ else:
+ prefix = re.search(
+ '(00|\+)[1-9]\d{,2}', international_phone.group())
+ target = prefix.group() + " [FILTERED]"
+ working_copy = working_copy.replace(
+ international_phone.group(), target)
+ return working_copy

Стефани обнови решението на 18.04.2014 19:11 (преди около 10 години)

import re
VALID_MAIL = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?'
VALID_MAIL_PREFIX = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@'
-VALID_HOST = '@[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?'
+VALID_HOST = '@([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
VALID_LOCAL_PHONE = '0[-\s\(\)]{,2}[1-9]([-\s\(\)]{,2}\d){6,10}\d?'
VALID_INTERNATIONAL_PHONE = '(00|\+)[1-9]\d{,2}([-\s\(\)]{,2}\d){6,10}\d?'
IP = '^(\d\.|[1-9]\d\.|1\d\d\.|2[0-5][0-6]\.){3}(\d|[1-9]\d|1\d\d|2[0-5][0-6])\Z'
class Validations:
@classmethod
def is_phone(self, value):
inner = '([-\s\(\)]{,2}\d){6,10}\d?\Z'
local = "^0[-\s\(\)]{,2}[1-9]" + inner
international = "^(00|\+)[1-9]\d{,2}" + inner
return bool(re.match(international, value))\
or bool(re.match(local, value))
@classmethod
def is_hostname(self, value):
- return bool(re.match('^[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?\Z', value))
+ return bool(re.match('^([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?\Z', value))
@classmethod
def is_email(self, value):
return bool(re.match(VALID_MAIL_PREFIX, value)) and \
self.is_hostname(value.split('@', 1)[1])
@classmethod
def is_ip_address(self, value):
return bool(re.match(IP, value))
@classmethod
def is_integer(self, value):
return bool(re.match('^-?(0|[1-9][0-9]*)\Z', value))
@classmethod
def is_number(self, value):
return bool(re.match('^-?(0[1-9]*|[1-9][0-9]*).?[0-9]*\Z', value))
@classmethod
def is_date(self, value):
return bool(re.match(
'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\d|3[0-1])\Z',
value))
@classmethod
def is_time(self, value):
return bool(re.match('^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\Z', value))
@classmethod
def is_datetime(self, value):
split_T = value.split('T', 1)
split_S = value.split(' ', 1)
return self.is_date(split_T[0]) and self.is_time(split_T[1]) or \
self.is_date(split_S[0]) and self.is_time(split_S[1])
class PrivacyFilter:
preserve_phone_country_code = False
preserve_email_hostname = False
partially_preserve_email_username = False
def __init__(self, value):
self.value = value
def filtered(self):
working_copy = self.value
while re.search(VALID_MAIL, working_copy):
mail = re.search(VALID_MAIL, working_copy).group()
host = re.search(VALID_HOST, mail).group()
prefix = re.search(
'[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,2}', mail).group()
- length = len(re.search(VALID_MAIL_PREFIX, mail).group())
+ length = len(re.search(VALID_MAIL_PREFIX, mail).group()) - 1
if self.partially_preserve_email_username and length < 6:
target = '[FILTERED]' + host
elif self.partially_preserve_email_username:
target = prefix + '[FILTERED]' + host
elif self.preserve_email_hostname:
target = '[FILTERED]' + host
else:
target = '[EMAIL]'
working_copy = working_copy.replace(mail, target)
while re.search(VALID_LOCAL_PHONE, working_copy) or \
re.search(VALID_INTERNATIONAL_PHONE, working_copy):
local_phone = re.search(VALID_LOCAL_PHONE, working_copy)
international_phone = re.search(
VALID_INTERNATIONAL_PHONE, working_copy)
if local_phone:
working_copy = working_copy.replace(
local_phone.group(), '[PHONE]')
elif not self.preserve_phone_country_code and international_phone:
working_copy = working_copy.replace(
international_phone.group(), '[PHONE]')
else:
prefix = re.search(
'(00|\+)[1-9]\d{,2}', international_phone.group())
target = prefix.group() + " [FILTERED]"
working_copy = working_copy.replace(
international_phone.group(), target)
return working_copy
+
  • Използвай \b, за да не филтрираш неща, които не трябва (например филтрираш международен телефон като обикновен)
  • Пренасяй по-дългите от 79 символа редове
  • На места си изпуснала възможност да преизползваш изразите, които си написала
  • Погледни пак как филтрираш международните телефони

Стефани обнови решението на 22.04.2014 21:40 (преди около 10 години)

import re
-VALID_MAIL = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@[a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?'
+VALID_MAIL = r'\b[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@[a-zA-Z0-9]'\
+ r'[a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.[a-zA-Z]{2,3}(\.[a-zA-Z]{,2})?\b'
VALID_MAIL_PREFIX = '[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,200}@'
-VALID_HOST = '@([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
-VALID_LOCAL_PHONE = '0[-\s\(\)]{,2}[1-9]([-\s\(\)]{,2}\d){6,10}\d?'
-VALID_INTERNATIONAL_PHONE = '(00|\+)[1-9]\d{,2}([-\s\(\)]{,2}\d){6,10}\d?'
-IP = '^(\d\.|[1-9]\d\.|1\d\d\.|2[0-5][0-6]\.){3}(\d|[1-9]\d|1\d\d|2[0-5][0-6])\Z'
+VALID_HOST = '@([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)'\
+ '+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
+VALID_LOCAL_PHONE = r'\b0[-\s\(\)]{,2}[1-9]([-\s\(\)]{,2}\d){6,10}\d?\b'
+INTERNATIONAL_PHONE = r"(\B\+|\b00)[1-9]\d{,2}([-\s\(\)]{,2}\d){6,10}\d?\b"
+IP = '^(\d\.|[1-9]\d\.|1\d\d\.|2[0-5][0-5]\.){3}'\
+ '(\d|[1-9]\d|1\d\d|2[0-5][0-5])\Z'
class Validations:
@classmethod
def is_phone(self, value):
inner = '([-\s\(\)]{,2}\d){6,10}\d?\Z'
local = "^0[-\s\(\)]{,2}[1-9]" + inner
international = "^(00|\+)[1-9]\d{,2}" + inner
return bool(re.match(international, value))\
or bool(re.match(local, value))
@classmethod
def is_hostname(self, value):
- return bool(re.match('^([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?\Z', value))
+ return bool(re.match('^' + VALID_HOST[1:] + '\Z', value))
@classmethod
def is_email(self, value):
return bool(re.match(VALID_MAIL_PREFIX, value)) and \
self.is_hostname(value.split('@', 1)[1])
@classmethod
def is_ip_address(self, value):
return bool(re.match(IP, value))
@classmethod
def is_integer(self, value):
return bool(re.match('^-?(0|[1-9][0-9]*)\Z', value))
@classmethod
def is_number(self, value):
return bool(re.match('^-?(0[1-9]*|[1-9][0-9]*).?[0-9]*\Z', value))
@classmethod
def is_date(self, value):
return bool(re.match(
'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2]\d|3[0-1])\Z',
value))
@classmethod
def is_time(self, value):
return bool(re.match('^([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d)\Z', value))
@classmethod
def is_datetime(self, value):
split_T = value.split('T', 1)
split_S = value.split(' ', 1)
return self.is_date(split_T[0]) and self.is_time(split_T[1]) or \
self.is_date(split_S[0]) and self.is_time(split_S[1])
class PrivacyFilter:
preserve_phone_country_code = False
preserve_email_hostname = False
partially_preserve_email_username = False
def __init__(self, value):
self.value = value
def filtered(self):
working_copy = self.value
while re.search(VALID_MAIL, working_copy):
mail = re.search(VALID_MAIL, working_copy).group()
host = re.search(VALID_HOST, mail).group()
prefix = re.search(
'[a-zA-Z0-9][a-zA-Z0-9_\+\.-]{,2}', mail).group()
length = len(re.search(VALID_MAIL_PREFIX, mail).group()) - 1
if self.partially_preserve_email_username and length < 6:
target = '[FILTERED]' + host
elif self.partially_preserve_email_username:
target = prefix + '[FILTERED]' + host
elif self.preserve_email_hostname:
target = '[FILTERED]' + host
else:
target = '[EMAIL]'
working_copy = working_copy.replace(mail, target)
while re.search(VALID_LOCAL_PHONE, working_copy) or \
- re.search(VALID_INTERNATIONAL_PHONE, working_copy):
+ re.search(INTERNATIONAL_PHONE, working_copy):
local_phone = re.search(VALID_LOCAL_PHONE, working_copy)
international_phone = re.search(
- VALID_INTERNATIONAL_PHONE, working_copy)
- if local_phone:
+ INTERNATIONAL_PHONE, working_copy)
+ if not self.preserve_phone_country_code and international_phone:
working_copy = working_copy.replace(
- local_phone.group(), '[PHONE]')
- elif not self.preserve_phone_country_code and international_phone:
- working_copy = working_copy.replace(
international_phone.group(), '[PHONE]')
- else:
+ elif self.preserve_phone_country_code and international_phone:
prefix = re.search(
'(00|\+)[1-9]\d{,2}', international_phone.group())
target = prefix.group() + " [FILTERED]"
working_copy = working_copy.replace(
international_phone.group(), target)
+ elif local_phone:
+ working_copy = working_copy.replace(
+ local_phone.group(), '[PHONE]')
return working_copy
-