Решение на Регулярни изрази от Гергана Петрова

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

Към профила на Гергана Петрова

Резултати

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

Код

import re
USER_PATTERN = r'[a-zA-Z0-9][\w\+\.-]{,200}'
HOSTNAME_PATTERN = r'([a-zA-Z0-9]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
NUMBER_PATTERN = r'-?(0|[1-9]\d*)(\.\d+)?'
INTEGER_PATTERN = r'-?(0|[1-9]\d*)'
DATE_PATTERN = r'\d{4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])'
TIME_PATTERN = r'([01]\d|2[0-3]):[0-5]\d:[0-5]\d'
INTERNATIONAL_PHONE_PATTERN = r'((00|\+)[1-9]{1,3})([ \(\)-]{,2}\d)+\d'
LOCAL_PHONE_PATTERN = r'0[ \(\)-]{,2}[1-9]([ \(\)-]{,2}\d){5,10}\d'
IP_ADDRESS_PATTERN = r'(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
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):
return self.phone_filtered(self.email_filtered(self.text))
def phone_filtered(self, text):
return self.local_phone_filtered(self.inter_phone_filtered(text))
def local_phone_filtered(self, text):
return re.sub(LOCAL_PHONE_PATTERN, '[PHONE]', text)
def inter_phone_filtered(self, text):
if self.preserve_phone_country_code:
return re.sub(INTERNATIONAL_PHONE_PATTERN, r'\1 [FILTERED]', text)
else:
return re.sub(INTERNATIONAL_PHONE_PATTERN, '[PHONE]', text)
def filter_email_match(self, match):
if len(match.group(1)) < 6:
return '[FILTERED]@' + match.group(2)
elif self.partially_preserve_email_username:
return match.group(1)[:3] + '[FILTERED]@' + match.group(2)
elif self.preserve_email_hostname:
return '[FILTERED]@' + match.group(2)
def email_filtered(self, text):
pattern = '(' + USER_PATTERN + ')' + '@' + '(' + HOSTNAME_PATTERN + ')'
if not(self.preserve_email_hostname or self.partially_preserve_email_username):
return re.sub(pattern, '[EMAIL]', text)
else:
return re.sub(pattern, self.filter_email_match, text)
class Validations:
@staticmethod
def full_match(pattern, text):
return re.match('\A' + pattern + '\Z', text)
@classmethod
def is_email(cls, value):
if value.count('@') != 1:
return False
else:
user, hostname = value.split('@')
return bool(cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname))
@classmethod
def is_phone(cls, value):
numbers = re.sub(r'^(00|\+)', '', re.sub(r'[ \(\)-]', '', value))
if re.match(r'00|\+', value) and len(numbers) in range(8, 13):
return bool(cls.full_match(INTERNATIONAL_PHONE_PATTERN, value))
elif re.match(r'0', value) and len(numbers) in range(7, 12):
return bool(cls.full_match(LOCAL_PHONE_PATTERN, value))
else:
return False
@classmethod
def is_hostname(cls, value):
return bool(cls.full_match(HOSTNAME_PATTERN, value))
@classmethod
def is_ip_address(cls, value):
return bool(cls.full_match(IP_ADDRESS_PATTERN, value))
@classmethod
def is_number(cls, value):
return bool(cls.full_match(NUMBER_PATTERN, value))
@classmethod
def is_integer(cls, value):
return bool(cls.full_match(INTEGER_PATTERN, value))
@classmethod
def is_date(cls, value):
return bool(cls.full_match(DATE_PATTERN, value))
@classmethod
def is_time(cls, value):
return bool(cls.full_match(TIME_PATTERN, value))
@classmethod
def is_datetime(cls, value):
try:
date, time = re.split(r'[ T]', value)
return cls.is_date(date) and cls.is_time(time)
except ValueError:
return False

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

...FF....F......F......................
======================================================================
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-lcxu9y/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-lcxu9y/test.py", line 86, in test_does_not_filter_invalid_phone_numbers
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: '0005551234569' != '0[PHONE]'
- 0005551234569
+ 0[PHONE]


======================================================================
FAIL: test_preserves_whitespace_around_phones (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-lcxu9y/test.py", line 89, in test_preserves_whitespace_around_phones
    self.assertEqual(' [PHONE] or...', solution.PrivacyFilter(' +359881212-12-1 2 or...').filtered())
AssertionError: ' [PHONE] or...' != ' [PHONE]-1 2 or...'
-  [PHONE] or...
+  [PHONE]-1 2 or...
?         ++++


======================================================================
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-lcxu9y/test.py", line 160, in test_can_validate_more_complex_phone_numbers
    self.assertIs(solution.Validations.is_phone(phone), valid)
AssertionError: False is not True

----------------------------------------------------------------------
Ran 39 tests in 0.049s

FAILED (failures=4)

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

Гергана обнови решението на 23.04.2014 00:57 (преди около 10 години)

+import re
+
+USER_PATTERN = r'\w[\w\+\.-]{,200}'
+HOSTNAME_PATTERN = r'([a-zA-Z\d][\w-]{,61}[^-]\.)+([a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)'
+NUMBER_PATTERN = r'-?(0|[1-9]\d*)(\.\d+)?'
+INTEGER_PATTERN = r'-?(0|[1-9]\d*)'
+DATE_PATTERN = r'\d{4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])'
+TIME_PATTERN = r'([01]\d|2[0-3]):[0-5]\d:[0-5]\d'
+INTERNATIONAL_PHONE_PATTERN = r'((00|\+)[1-9]{1,3})([ \(\)-]{,2}\d)+\d'
+LOCAL_PHONE_PATTERN = r'0[ \(\)-]{,2}[1-9]([ \(\)-]{,2}\d){5,10}\d'
+
+
+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):
+ return self.phone_filtered(self.email_filtered(self.text))
+
+ def phone_filtered(self, text):
+ return self.local_phone_filtered(self.inter_phone_filtered(text))
+
+ def local_phone_filtered(self, text):
+ return re.sub(LOCAL_PHONE_PATTERN, '[PHONE]', text)
+
+ def inter_phone_filtered(self, text):
+ if self.preserve_phone_country_code:
+ return re.sub(INTERNATIONAL_PHONE_PATTERN, r'\1 [FILTERED]', text)
+ else:
+ return re.sub(INTERNATIONAL_PHONE_PATTERN, '[FILTERED]', text)
+
+ def filter_email_match(self, match):
+ if self.partially_preserve_email_username:
+ if len(match.group(1)) < 6:
+ return '[FILTERED]@' + match.group(2)
+ else:
+ return match.group(1)[:3] + '[FILTERED]@' + match.group(2)
+ elif self.preserve_email_hostname:
+ return '[FILTERED]@' + match.group(2)
+ else:
+ return '[EMAIL]'
+
+ def email_filtered(self, text):
+ pattern = '(' + USER_PATTERN + ')' + '@' + '(' + HOSTNAME_PATTERN + ')'
+ return re.sub(pattern, self.filter_email_match, text)
+
+
+class Validations:
+ @staticmethod
+ def full_match(pattern, text):
+ return re.match(pattern, text)
+
+ @classmethod
+ def is_email(cls, value):
+ user, hostname = value.split('@')
+ if cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname):
+ return True
+ return False
+
+ @classmethod
+ def is_phone(cls, value):
+ numbers = re.sub(r'^(00|\+)', '', re.sub(r'[ \(\)-]', '', value))
+ if re.match(r'00|\+', value) and len(numbers) in range(8, 13):
+ if cls.full_match(INTERNATIONAL_PHONE_PATTERN, value):
+ return True
+ elif re.match(r'0', value) and len(numbers) in range(7, 12):
+ if cls.full_match(LOCAL_PHONE_PATTERN, value):
+ return True
+ else:
+ return False
+
+ @classmethod
+ def is_hostname(cls, value):
+ if cls.full_match(HOSTNAME_PATTERN, value):
+ return True
+ return False
+
+ @classmethod
+ def is_ip_address(cls, value):
+ ip_address = value.split('.')
+ return len(ip_address) == 4 and \
+ all(int(byte) in range(0, 256) for byte in ip_address)
+
+ @classmethod
+ def is_number(cls, value):
+ if cls.full_match(NUMBER_PATTERN, value):
+ return True
+ return False
+
+ @classmethod
+ def is_integer(cls, value):
+ if cls.full_match(INTEGER_PATTERN, value):
+ return True
+ return False
+
+ @classmethod
+ def is_date(cls, value):
+ if cls.full_match(DATE_PATTERN, value):
+ return True
+ return False
+
+ @classmethod
+ def is_time(cls, value):
+ if cls.full_match(TIME_PATTERN, value):
+ return True
+ return False
+
+ @classmethod
+ def is_datetime(cls, value):
+ try:
+ date, time = re.split(r'[ T]', value)
+ return cls.is_date(date) and cls.is_time(time)
+ except ValueError:
+ return False

Гергана обнови решението на 23.04.2014 09:22 (преди около 10 години)

import re
-USER_PATTERN = r'\w[\w\+\.-]{,200}'
-HOSTNAME_PATTERN = r'([a-zA-Z\d][\w-]{,61}[^-]\.)+([a-zA-Z]{2,3}(\.[a-zA-Z]{2})?)'
+USER_PATTERN = r'[a-zA-Z0-9][\w\+\.-]{,200}'
+HOSTNAME_PATTERN = r'([a-zA-Z0-9]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
NUMBER_PATTERN = r'-?(0|[1-9]\d*)(\.\d+)?'
INTEGER_PATTERN = r'-?(0|[1-9]\d*)'
DATE_PATTERN = r'\d{4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])'
TIME_PATTERN = r'([01]\d|2[0-3]):[0-5]\d:[0-5]\d'
INTERNATIONAL_PHONE_PATTERN = r'((00|\+)[1-9]{1,3})([ \(\)-]{,2}\d)+\d'
LOCAL_PHONE_PATTERN = r'0[ \(\)-]{,2}[1-9]([ \(\)-]{,2}\d){5,10}\d'
+IP_ADDRESS_PATTERN = r'(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
-
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):
return self.phone_filtered(self.email_filtered(self.text))
def phone_filtered(self, text):
return self.local_phone_filtered(self.inter_phone_filtered(text))
def local_phone_filtered(self, text):
return re.sub(LOCAL_PHONE_PATTERN, '[PHONE]', text)
def inter_phone_filtered(self, text):
if self.preserve_phone_country_code:
return re.sub(INTERNATIONAL_PHONE_PATTERN, r'\1 [FILTERED]', text)
else:
return re.sub(INTERNATIONAL_PHONE_PATTERN, '[FILTERED]', text)
def filter_email_match(self, match):
if self.partially_preserve_email_username:
if len(match.group(1)) < 6:
return '[FILTERED]@' + match.group(2)
else:
return match.group(1)[:3] + '[FILTERED]@' + match.group(2)
elif self.preserve_email_hostname:
return '[FILTERED]@' + match.group(2)
else:
return '[EMAIL]'
def email_filtered(self, text):
pattern = '(' + USER_PATTERN + ')' + '@' + '(' + HOSTNAME_PATTERN + ')'
return re.sub(pattern, self.filter_email_match, text)
class Validations:
+
@staticmethod
def full_match(pattern, text):
- return re.match(pattern, text)
+ return re.match('\A' + pattern + '\Z', text)
@classmethod
def is_email(cls, value):
user, hostname = value.split('@')
- if cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname):
- return True
- return False
+ return bool(cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname))
@classmethod
def is_phone(cls, value):
numbers = re.sub(r'^(00|\+)', '', re.sub(r'[ \(\)-]', '', value))
if re.match(r'00|\+', value) and len(numbers) in range(8, 13):
- if cls.full_match(INTERNATIONAL_PHONE_PATTERN, value):
- return True
+ return bool(cls.full_match(INTERNATIONAL_PHONE_PATTERN, value))
elif re.match(r'0', value) and len(numbers) in range(7, 12):
- if cls.full_match(LOCAL_PHONE_PATTERN, value):
- return True
+ return bool(cls.full_match(LOCAL_PHONE_PATTERN, value))
else:
return False
@classmethod
def is_hostname(cls, value):
- if cls.full_match(HOSTNAME_PATTERN, value):
- return True
- return False
+ return bool(cls.full_match(HOSTNAME_PATTERN, value))
@classmethod
def is_ip_address(cls, value):
- ip_address = value.split('.')
- return len(ip_address) == 4 and \
- all(int(byte) in range(0, 256) for byte in ip_address)
+ return bool(cls.full_match(IP_ADDRESS_PATTERN, value))
@classmethod
def is_number(cls, value):
- if cls.full_match(NUMBER_PATTERN, value):
- return True
- return False
+ return bool(cls.full_match(NUMBER_PATTERN, value))
@classmethod
def is_integer(cls, value):
- if cls.full_match(INTEGER_PATTERN, value):
- return True
- return False
+ return bool(cls.full_match(INTEGER_PATTERN, value))
@classmethod
def is_date(cls, value):
- if cls.full_match(DATE_PATTERN, value):
- return True
- return False
+ return bool(cls.full_match(DATE_PATTERN, value))
@classmethod
def is_time(cls, value):
- if cls.full_match(TIME_PATTERN, value):
- return True
- return False
+ return bool(cls.full_match(TIME_PATTERN, value))
@classmethod
def is_datetime(cls, value):
try:
date, time = re.split(r'[ T]', value)
return cls.is_date(date) and cls.is_time(time)
except ValueError:
return False

Гергана обнови решението на 23.04.2014 13:40 (преди около 10 години)

import re
USER_PATTERN = r'[a-zA-Z0-9][\w\+\.-]{,200}'
HOSTNAME_PATTERN = r'([a-zA-Z0-9]([0-9a-zA-Z-]{,61}[0-9a-zA-Z])?\.)+[a-zA-Z]{2,3}(\.[a-zA-Z]{2})?'
NUMBER_PATTERN = r'-?(0|[1-9]\d*)(\.\d+)?'
INTEGER_PATTERN = r'-?(0|[1-9]\d*)'
DATE_PATTERN = r'\d{4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])'
TIME_PATTERN = r'([01]\d|2[0-3]):[0-5]\d:[0-5]\d'
INTERNATIONAL_PHONE_PATTERN = r'((00|\+)[1-9]{1,3})([ \(\)-]{,2}\d)+\d'
LOCAL_PHONE_PATTERN = r'0[ \(\)-]{,2}[1-9]([ \(\)-]{,2}\d){5,10}\d'
IP_ADDRESS_PATTERN = r'(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'
+
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):
return self.phone_filtered(self.email_filtered(self.text))
def phone_filtered(self, text):
return self.local_phone_filtered(self.inter_phone_filtered(text))
def local_phone_filtered(self, text):
return re.sub(LOCAL_PHONE_PATTERN, '[PHONE]', text)
def inter_phone_filtered(self, text):
if self.preserve_phone_country_code:
return re.sub(INTERNATIONAL_PHONE_PATTERN, r'\1 [FILTERED]', text)
else:
- return re.sub(INTERNATIONAL_PHONE_PATTERN, '[FILTERED]', text)
+ return re.sub(INTERNATIONAL_PHONE_PATTERN, '[PHONE]', text)
def filter_email_match(self, match):
- if self.partially_preserve_email_username:
- if len(match.group(1)) < 6:
- return '[FILTERED]@' + match.group(2)
- else:
- return match.group(1)[:3] + '[FILTERED]@' + match.group(2)
+ if len(match.group(1)) < 6:
+ return '[FILTERED]@' + match.group(2)
+ elif self.partially_preserve_email_username:
+ return match.group(1)[:3] + '[FILTERED]@' + match.group(2)
elif self.preserve_email_hostname:
return '[FILTERED]@' + match.group(2)
- else:
- return '[EMAIL]'
def email_filtered(self, text):
pattern = '(' + USER_PATTERN + ')' + '@' + '(' + HOSTNAME_PATTERN + ')'
- return re.sub(pattern, self.filter_email_match, text)
+ if not(self.preserve_email_hostname or self.partially_preserve_email_username):
+ return re.sub(pattern, '[EMAIL]', text)
+ else:
+ return re.sub(pattern, self.filter_email_match, text)
class Validations:
@staticmethod
def full_match(pattern, text):
return re.match('\A' + pattern + '\Z', text)
@classmethod
def is_email(cls, value):
- user, hostname = value.split('@')
- return bool(cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname))
+ if value.count('@') != 1:
+ return False
+ else:
+ user, hostname = value.split('@')
+ return bool(cls.full_match(USER_PATTERN, user) and cls.is_hostname(hostname))
@classmethod
def is_phone(cls, value):
numbers = re.sub(r'^(00|\+)', '', re.sub(r'[ \(\)-]', '', value))
if re.match(r'00|\+', value) and len(numbers) in range(8, 13):
return bool(cls.full_match(INTERNATIONAL_PHONE_PATTERN, value))
elif re.match(r'0', value) and len(numbers) in range(7, 12):
return bool(cls.full_match(LOCAL_PHONE_PATTERN, value))
else:
return False
@classmethod
def is_hostname(cls, value):
return bool(cls.full_match(HOSTNAME_PATTERN, value))
@classmethod
def is_ip_address(cls, value):
return bool(cls.full_match(IP_ADDRESS_PATTERN, value))
@classmethod
def is_number(cls, value):
return bool(cls.full_match(NUMBER_PATTERN, value))
@classmethod
def is_integer(cls, value):
return bool(cls.full_match(INTEGER_PATTERN, value))
@classmethod
def is_date(cls, value):
return bool(cls.full_match(DATE_PATTERN, value))
@classmethod
def is_time(cls, value):
return bool(cls.full_match(TIME_PATTERN, value))
@classmethod
def is_datetime(cls, value):
try:
date, time = re.split(r'[ T]', value)
return cls.is_date(date) and cls.is_time(time)
except ValueError:
return False