Решение на Регулярни изрази от Цветелина Борисова

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

Към профила на Цветелина Борисова

Резултати

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

Код

import re
INT_PHONE = r'(00|\+)[1-9]{1,3}(([1-9](\s|\-|\(|\)){,2}){6,10}\d)$'
LOCAL_PHONE = r'0([1-9](\s|\-|\(|\)){,2}){6,10}\d$'
EMAIL = r'(\w(\w|\-|\+|\.|\_){,200})@'
TIME = r'^([0-1]\d|2[0-3]){,2}\:([0-5]\d){,2}\:([0-5]\d){,2}$'
DATE = r'00\d\d|[1-9]\d{3}\-(0[1-9]|1[0-2])\-(0[1-9]|(1|2)\d|3(0|1))$'
NUMBER = r'\-*(0\.\d+|[1-9]+\.*\d+)$'
INTEGER = r'\-*0|[1-9]\d+$'
HOSTNAME = r'(\w(\w|\-){0,61}\w{0,1}\.)+[A-Za-z]{2,3}(\.[A-Za-z]){,1}$'
IP_ADDRESS = r'(\d|(\d|1\d|2[0-4])\d|25[0-5])$'
SEARCH_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL + HOSTNAME],
'email': [0, '[EMAIL]', EMAIL + HOSTNAME],
'int_phone': [0, '[PHONE]', INT_PHONE],
'local_phone': [0, '[PHONE]', LOCAL_PHONE],
'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE]}
class PrivacyFilter:
def __init__(self, data_to_filter):
self.__data = data_to_filter
self.partially_preserve_email_username = False
self.preserve_email_hostname = False
self.preserve_phone_country_code = False
@property
def data(self):
return self.__data
def filtered(self):
repl = self.data
config = ''
if re.search(INT_PHONE, self.data):
config = SEARCH_CONFIG['int_phone']
if self.preserve_phone_country_code:
config = SEARCH_CONFIG['int_phone_preserve']
elif re.search(LOCAL_PHONE, self.data):
config = SEARCH_CONFIG['local_phone']
elif re.search(EMAIL + HOSTNAME, self.data):
config = SEARCH_CONFIG['email_preserve']
if self.partially_preserve_email_username:
repl = repl[3:]
elif not self.preserve_email_hostname:
config = SEARCH_CONFIG['email']
if not config == '':
string_to_be_replaced = re.search(config[2], repl).group(config[0])
return self.data.replace(string_to_be_replaced, config[1])
else:
return self.data
class Validations:
@classmethod
def is_time(cls, value):
return re.search(TIME, value) is not None
@classmethod
def is_int_phone(cls, value):
return re.match(INT_PHONE, value) is not None
@classmethod
def is_local_phone(cls, value):
return re.match(LOCAL_PHONE, value) is not None
@classmethod
def is_phone(cls, value):
return cls.is_int_phone(value) or cls.is_local_phone(value)
@classmethod
def is_number(cls, value):
return re.match(NUMBER, value) is not None
@classmethod
def is_integer(cls, value):
return re.match(INTEGER, value) is not None
@classmethod
def is_hostname(cls, value):
return re.match(HOSTNAME, value) is not None
@classmethod
def is_date(cls, value):
return re.match(DATE, value) is not None
@classmethod
def is_email(cls, value):
return re.match(EMAIL + HOSTNAME, value) is not None
@classmethod
def is_datetime(cls, value):
vals = value.split()
if len(vals) != 2:
return False
return cls.is_time(vals[1]) and cls.is_date(vals[0])
@classmethod
def is_ip_address(cls, value):
bytes = value.split('.')
if not len(bytes) == 4:
return False
return all(re.match(IP_ADDRESS, byte) is not None for byte in bytes)

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

...FFFEF.FF....FF.....FF..FF...FF.FFF..
======================================================================
ERROR: test_filters_whole_email_usernames_if_too_short (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-blgpg/test.py", line 61, in test_filters_whole_email_usernames_if_too_short
    self.assertEqual('[FILTERED]@example.com', self.partially_filter_email_usernames('me@example.com'))
  File "/tmp/d20140513-11348-blgpg/test.py", line 16, in partially_filter_email_usernames
    return filter.filtered()
  File "/tmp/d20140513-11348-blgpg/solution.py", line 48, in filtered
    string_to_be_replaced = re.search(config[2], repl).group(config[0])
AttributeError: 'NoneType' object has no attribute 'group'

======================================================================
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-blgpg/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-blgpg/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_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-blgpg/test.py", line 76, in test_filters_more_complex_phone_numbers
    self.assertEqual(filtered, solution.PrivacyFilter(text).filtered())
AssertionError: '[PHONE]' != '+1 555 123-456'
- [PHONE]
+ +1 555 123-456


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


======================================================================
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-blgpg/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...' != ' +359881212-12-1 2 or...'
-  [PHONE] or...
+  +359881212-12-1 2 or...


======================================================================
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-blgpg/test.py", line 100, in test_separates_preserved_country_code_from_filtered_phone_with_a_space
    self.assertEqual(filtered, filter.filtered())
AssertionError: 'Phone: 0025 [FILTERED]' != 'Phone: 002 [FILTERED]'
- Phone: 0025 [FILTERED]
?           -
+ Phone: 002 [FILTERED]


======================================================================
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-blgpg/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-blgpg/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

======================================================================
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-blgpg/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-blgpg/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-blgpg/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-blgpg/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-blgpg/test.py", line 278, in test_validates_datetime_values
    self.assertTrue(solution.Validations.is_datetime('2012-11-19T19:00:00'))
AssertionError: False is not true

======================================================================
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-blgpg/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_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-blgpg/test.py", line 225, in test_validates_more_complex_integers
    self.assertFalse(solution.Validations.is_integer('00'))
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-blgpg/test.py", line 204, in test_validates_more_complex_numbers
    self.assertTrue(solution.Validations.is_number('0'))
AssertionError: False is not true

======================================================================
FAIL: test_validates_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-blgpg/test.py", line 197, in test_validates_numbers
    self.assertTrue(solution.Validations.is_number('9'))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 39 tests in 0.041s

FAILED (failures=17, errors=1)

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

Цветелина обнови решението на 18.04.2014 22:38 (преди над 10 години)

+import re
+
+INT_PHONE_PATTERN = r'(00|\+)[1-9]{1,3}((\d|\s|\-|\(|\){2}){6,}[^(\s|\(|\)|\-)])$'
+LOC_PHONE_PATTERN = r'0\W|[^\+|\:|\s](\d|\s|\-|\(|\){2}){6,}[^(\s|\-|\(|\)]$'
+EMAIL_PATTERN = r'([\w{,200}]+)@[\w\-]{,61}[^-]\.[A-Za-z]{2,3}\.*[A-Za-z]{,3}$'
+TIME_PATTERN = r'^([0-1]\d|2[0-3]){,2}\:([0-5]\d){,2}\:([0-5]\d){,2}$'
+DATE_PATTERN = r'00\d\d|[1-9]\d{3}\-(0[1-9]|1[0-2])\-(0[1-9]|(1|2)\d|3(0|1))$'
+NUMBER_PATTERN = r'^\-*(0\.\d+|[1-9]+\.*\d+)$'
+INTEGER_PATTERN = r'^\-*0|[1-9]\d+$'
+HOSTNAME_PATTERN = r'\w((\w\-*){,61}\w\.)+[A-Za-z]{2,3}(\.[A-Za-z])*$'
+IP_PATTERN = r'((\d|(\d|1\d|2[0-4])\d|25[0-5])\.){3}(\d|(\d|1\d|2[0-4])\d|25[0-5])$'
+
+
+PATTERN_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL_PATTERN],
+ 'email': [0, '[EMAIL]', EMAIL_PATTERN],
+ 'int_phone': [0, '[PHONE]', INT_PHONE_PATTERN],
+ 'local_phone': [0, '[PHONE]', LOC_PHONE_PATTERN],
+ 'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE_PATTERN]}
+
+
+class PrivacyFilter:
+ def __init__(self, data_to_filter):
+ self.__data = data_to_filter
+ self.partially_preserve_email_username = False
+ self.preserve_email_hostname = False
+ self.preserve_phone_country_code = False
+
+ @property
+ def data(self):
+ return self.__data
+
+ def filtered(self):
+ repl = self.data
+
+ if re.search(INT_PHONE_PATTERN, self.data):
+ config = PATTERN_CONFIG['int_phone']
+ if self.preserve_phone_country_code:
+ config = PATTERN_CONFIG['int_phone_preserve']
+ elif re.search(LOC_PHONE_PATTERN, self.data):
+ config = PATTERN_CONFIG['local_phone']
+ elif re.search(EMAIL_PATTERN, self.data):
+ config = PATTERN_CONFIG['email_preserve']
+ if self.partially_preserve_email_username:
+ repl = repl[3:]
+ elif not self.preserve_email_hostname:
+ config = PATTERN_CONFIG['email']
+
+ string_to_be_replaced = re.search(config[2], repl).group(config[0])
+ return self.data.replace(string_to_be_replaced, config[1])
+
+
+class Validations:
+ @classmethod
+ def is_time(cls, value):
+ return re.search(TIME_PATTERN, value)
+
+ @classmethod
+ def is_int_phone(cls, value):
+ return re.search(INT_PHONE_PATTERN, value)
+
+ @classmethod
+ def is_local_phone(cls, value):
+ return re.search(LOC_PHONE_PATTERN, value)
+
+ @classmethod
+ def is_phone(cls, value):
+ return cls.is_int_phone(value) or cls.is_local_phone(value)
+
+ @classmethod
+ def is_number(cls, value):
+ return re.search(NUMBER_PATTERN, value)
+
+ @classmethod
+ def is_integer(cls, value):
+ return re.search(INTEGER_PATTERN, value)
+
+ @classmethod
+ def is_hostname(cls, value):
+ return re.match(HOSTNAME_PATTERN, value)
+
+ @classmethod
+ def is_date(cls, value):
+ return re.match(DATE_PATTERN, value)
+
+ @classmethod
+ def is_email(cls, value):
+ return re.search(EMAIL_PATTERN, value)
+
+ @classmethod
+ def is_datetime(cls, value):
+ values = value.split()
+ if len(values) == 2:
+ return cls.is_time(values[1]) and cls.is_date(values[0])
+ else:
+ return False
+
+ @classmethod
+ def is_ip_address(cls, value):
+ return re.match(IP_PATTERN, value)

Pattern-ите, които съм дефинирала в началото на файла не ми харесват, но не можах да направя по-добри. Не е хубаво да са толкова сложни и нечетими нали? И не знам ли дали може да ми помогнете, но не успях да намеря как да ползвам част от един pattern в друг, например INT_PHONE_PATTERN има еднаква част с LOC_PHONE_PATTERN.

Цветелина обнови решението на 21.04.2014 16:22 (преди над 10 години)

import re
-INT_PHONE_PATTERN = r'(00|\+)[1-9]{1,3}((\d|\s|\-|\(|\){2}){6,}[^(\s|\(|\)|\-)])$'
-LOC_PHONE_PATTERN = r'0\W|[^\+|\:|\s](\d|\s|\-|\(|\){2}){6,}[^(\s|\-|\(|\)]$'
+INT_PHONE_PATTERN = r'(00|\+)[1-9]{1,3}(([1-9](\s|\-|\(|\)){,2}){6,11}[^(\s|\(|\)|\-)])$'
+LOC_PHONE_PATTERN = r'0([1-9](\s|\-|\(|\)){,2}){6,11}[^(\s|\(|\)|\-)]$'
EMAIL_PATTERN = r'([\w{,200}]+)@[\w\-]{,61}[^-]\.[A-Za-z]{2,3}\.*[A-Za-z]{,3}$'
TIME_PATTERN = r'^([0-1]\d|2[0-3]){,2}\:([0-5]\d){,2}\:([0-5]\d){,2}$'
DATE_PATTERN = r'00\d\d|[1-9]\d{3}\-(0[1-9]|1[0-2])\-(0[1-9]|(1|2)\d|3(0|1))$'
NUMBER_PATTERN = r'^\-*(0\.\d+|[1-9]+\.*\d+)$'
INTEGER_PATTERN = r'^\-*0|[1-9]\d+$'
HOSTNAME_PATTERN = r'\w((\w\-*){,61}\w\.)+[A-Za-z]{2,3}(\.[A-Za-z])*$'
IP_PATTERN = r'((\d|(\d|1\d|2[0-4])\d|25[0-5])\.){3}(\d|(\d|1\d|2[0-4])\d|25[0-5])$'
-PATTERN_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL_PATTERN],
- 'email': [0, '[EMAIL]', EMAIL_PATTERN],
- 'int_phone': [0, '[PHONE]', INT_PHONE_PATTERN],
- 'local_phone': [0, '[PHONE]', LOC_PHONE_PATTERN],
- 'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE_PATTERN]}
+SEARCH_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL_PATTERN],
+ 'email': [0, '[EMAIL]', EMAIL_PATTERN],
+ 'int_phone': [0, '[PHONE]', INT_PHONE_PATTERN],
+ 'local_phone': [0, '[PHONE]', LOC_PHONE_PATTERN],
+ 'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE_PATTERN]}
class PrivacyFilter:
def __init__(self, data_to_filter):
self.__data = data_to_filter
self.partially_preserve_email_username = False
self.preserve_email_hostname = False
self.preserve_phone_country_code = False
@property
def data(self):
return self.__data
def filtered(self):
repl = self.data
if re.search(INT_PHONE_PATTERN, self.data):
- config = PATTERN_CONFIG['int_phone']
+ config = SEARCH_CONFIG['int_phone']
if self.preserve_phone_country_code:
- config = PATTERN_CONFIG['int_phone_preserve']
+ config = SEARCH_CONFIG['int_phone_preserve']
elif re.search(LOC_PHONE_PATTERN, self.data):
- config = PATTERN_CONFIG['local_phone']
+ config = SEARCH_CONFIG['local_phone']
elif re.search(EMAIL_PATTERN, self.data):
- config = PATTERN_CONFIG['email_preserve']
+ config = SEARCH_CONFIG['email_preserve']
if self.partially_preserve_email_username:
repl = repl[3:]
elif not self.preserve_email_hostname:
- config = PATTERN_CONFIG['email']
+ config = SEARCH_CONFIG['email']
string_to_be_replaced = re.search(config[2], repl).group(config[0])
return self.data.replace(string_to_be_replaced, config[1])
class Validations:
@classmethod
def is_time(cls, value):
return re.search(TIME_PATTERN, value)
@classmethod
def is_int_phone(cls, value):
- return re.search(INT_PHONE_PATTERN, value)
+ return re.match(INT_PHONE_PATTERN, value)
@classmethod
def is_local_phone(cls, value):
- return re.search(LOC_PHONE_PATTERN, value)
+ return re.match(LOC_PHONE_PATTERN, value)
@classmethod
def is_phone(cls, value):
return cls.is_int_phone(value) or cls.is_local_phone(value)
@classmethod
def is_number(cls, value):
return re.search(NUMBER_PATTERN, value)
@classmethod
def is_integer(cls, value):
return re.search(INTEGER_PATTERN, value)
@classmethod
def is_hostname(cls, value):
return re.match(HOSTNAME_PATTERN, value)
@classmethod
def is_date(cls, value):
return re.match(DATE_PATTERN, value)
@classmethod
def is_email(cls, value):
return re.search(EMAIL_PATTERN, value)
@classmethod
def is_datetime(cls, value):
values = value.split()
if len(values) == 2:
return cls.is_time(values[1]) and cls.is_date(values[0])
else:
return False
@classmethod
def is_ip_address(cls, value):
return re.match(IP_PATTERN, value)
  • Използвай \b
  • Валидаторите ти трябва да връщат True или False
  • Променливата ти config е дефинирана в if-a, а я използваш извън него, което може да ти създаде проблеми в някои случаи
  • А за да ги използваш, можеш да работиш с тях като със стрингове

Цветелина обнови решението на 22.04.2014 22:01 (преди над 10 години)

import re
-INT_PHONE_PATTERN = r'(00|\+)[1-9]{1,3}(([1-9](\s|\-|\(|\)){,2}){6,11}[^(\s|\(|\)|\-)])$'
-LOC_PHONE_PATTERN = r'0([1-9](\s|\-|\(|\)){,2}){6,11}[^(\s|\(|\)|\-)]$'
-EMAIL_PATTERN = r'([\w{,200}]+)@[\w\-]{,61}[^-]\.[A-Za-z]{2,3}\.*[A-Za-z]{,3}$'
-TIME_PATTERN = r'^([0-1]\d|2[0-3]){,2}\:([0-5]\d){,2}\:([0-5]\d){,2}$'
-DATE_PATTERN = r'00\d\d|[1-9]\d{3}\-(0[1-9]|1[0-2])\-(0[1-9]|(1|2)\d|3(0|1))$'
-NUMBER_PATTERN = r'^\-*(0\.\d+|[1-9]+\.*\d+)$'
-INTEGER_PATTERN = r'^\-*0|[1-9]\d+$'
-HOSTNAME_PATTERN = r'\w((\w\-*){,61}\w\.)+[A-Za-z]{2,3}(\.[A-Za-z])*$'
-IP_PATTERN = r'((\d|(\d|1\d|2[0-4])\d|25[0-5])\.){3}(\d|(\d|1\d|2[0-4])\d|25[0-5])$'
+INT_PHONE = r'(00|\+)[1-9]{1,3}(([1-9](\s|\-|\(|\)){,2}){6,10}\d)$'
+LOCAL_PHONE = r'0([1-9](\s|\-|\(|\)){,2}){6,10}\d$'
+EMAIL = r'(\w(\w|\-|\+|\.|\_){,200})@'
+TIME = r'^([0-1]\d|2[0-3]){,2}\:([0-5]\d){,2}\:([0-5]\d){,2}$'
+DATE = r'00\d\d|[1-9]\d{3}\-(0[1-9]|1[0-2])\-(0[1-9]|(1|2)\d|3(0|1))$'
+NUMBER = r'\-*(0\.\d+|[1-9]+\.*\d+)$'
+INTEGER = r'\-*0|[1-9]\d+$'
+HOSTNAME = r'(\w(\w|\-){0,61}\w{0,1}\.)+[A-Za-z]{2,3}(\.[A-Za-z]){,1}$'
+IP_ADDRESS = r'(\d|(\d|1\d|2[0-4])\d|25[0-5])$'
-SEARCH_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL_PATTERN],
- 'email': [0, '[EMAIL]', EMAIL_PATTERN],
- 'int_phone': [0, '[PHONE]', INT_PHONE_PATTERN],
- 'local_phone': [0, '[PHONE]', LOC_PHONE_PATTERN],
- 'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE_PATTERN]}
+SEARCH_CONFIG = {'email_preserve': [1, '[FILTERED]', EMAIL + HOSTNAME],
+ 'email': [0, '[EMAIL]', EMAIL + HOSTNAME],
+ 'int_phone': [0, '[PHONE]', INT_PHONE],
+ 'local_phone': [0, '[PHONE]', LOCAL_PHONE],
+ 'int_phone_preserve': [2, ' [FILTERED]', INT_PHONE]}
class PrivacyFilter:
def __init__(self, data_to_filter):
self.__data = data_to_filter
self.partially_preserve_email_username = False
self.preserve_email_hostname = False
self.preserve_phone_country_code = False
@property
def data(self):
return self.__data
def filtered(self):
repl = self.data
-
- if re.search(INT_PHONE_PATTERN, self.data):
+ config = ''
+ if re.search(INT_PHONE, self.data):
config = SEARCH_CONFIG['int_phone']
if self.preserve_phone_country_code:
config = SEARCH_CONFIG['int_phone_preserve']
- elif re.search(LOC_PHONE_PATTERN, self.data):
+ elif re.search(LOCAL_PHONE, self.data):
config = SEARCH_CONFIG['local_phone']
- elif re.search(EMAIL_PATTERN, self.data):
+ elif re.search(EMAIL + HOSTNAME, self.data):
config = SEARCH_CONFIG['email_preserve']
if self.partially_preserve_email_username:
repl = repl[3:]
elif not self.preserve_email_hostname:
config = SEARCH_CONFIG['email']
+ if not config == '':
+ string_to_be_replaced = re.search(config[2], repl).group(config[0])
+ return self.data.replace(string_to_be_replaced, config[1])
+ else:
+ return self.data
- string_to_be_replaced = re.search(config[2], repl).group(config[0])
- return self.data.replace(string_to_be_replaced, config[1])
-
class Validations:
@classmethod
def is_time(cls, value):
- return re.search(TIME_PATTERN, value)
+ return re.search(TIME, value) is not None
@classmethod
def is_int_phone(cls, value):
- return re.match(INT_PHONE_PATTERN, value)
+ return re.match(INT_PHONE, value) is not None
@classmethod
def is_local_phone(cls, value):
- return re.match(LOC_PHONE_PATTERN, value)
+ return re.match(LOCAL_PHONE, value) is not None
@classmethod
def is_phone(cls, value):
return cls.is_int_phone(value) or cls.is_local_phone(value)
@classmethod
def is_number(cls, value):
- return re.search(NUMBER_PATTERN, value)
+ return re.match(NUMBER, value) is not None
@classmethod
def is_integer(cls, value):
- return re.search(INTEGER_PATTERN, value)
+ return re.match(INTEGER, value) is not None
@classmethod
def is_hostname(cls, value):
- return re.match(HOSTNAME_PATTERN, value)
+ return re.match(HOSTNAME, value) is not None
@classmethod
def is_date(cls, value):
- return re.match(DATE_PATTERN, value)
+ return re.match(DATE, value) is not None
@classmethod
def is_email(cls, value):
- return re.search(EMAIL_PATTERN, value)
+ return re.match(EMAIL + HOSTNAME, value) is not None
@classmethod
def is_datetime(cls, value):
- values = value.split()
- if len(values) == 2:
- return cls.is_time(values[1]) and cls.is_date(values[0])
- else:
+ vals = value.split()
+ if len(vals) != 2:
return False
+ return cls.is_time(vals[1]) and cls.is_date(vals[0])
@classmethod
def is_ip_address(cls, value):
- return re.match(IP_PATTERN, value)
+ bytes = value.split('.')
+ if not len(bytes) == 4:
+ return False
+ return all(re.match(IP_ADDRESS, byte) is not None for byte in bytes)

" И не знам ли дали може да ми помогнете, но не успях да намеря как да ползвам част от един pattern в друг, например INT_PHONE_PATTERN има еднаква част с LOC_PHONE_PATTERN."

Цвети, така няма ли да стане :

PHONE_PATTERN='(([1-9](\s|\-|\(|\)){,2}){6,10}'

INT_PHONE = r'(00|\+)[1-9]{1,3}'+PHONE_PATTERN+'\d)$'

LOCAL_PHONE = r'0'+PHONE_PATTERN+'\d$'