import re
text = "В тексте есть номер заказа 12345 и еще 678."
pattern = r"\d+" # Ищем одну или более цифр подряд
match = re.search(pattern, text)
if match:
print(f"Найдено первое число: {match.group()}")
print(f"Оно начинается на позиции: {match.start()}")
print(f"И заканчивается на позиции: {match.end()}")
else:
print("Числа не найдены.")
# Найдено первое число: 12345
# Оно начинается на позиции: 26
# И заканчивается на позиции: 31
text1 = "Заказ 9876 обработан."
text2 = "Обработан заказ 9876."
pattern = r"Заказ \d+" # Ищем "Заказ", пробел, затем одну или более цифр
match1 = re.match(pattern, text1)
match2 = re.match(pattern, text2)
print(f"Результат для text1: {match1.group() if match1 else None}")
# Результат для text1: Заказ 9876
print(f"Результат для text2: {match2.group() if match2 else None}")
# Результат для text2: None
is_date = re.match(r'\d{2}.\d{2}.\d{4}', '15.07.2023: Заметка')
print(bool(is_date)) # True
text = "Контакты: +7 (123) 456-78-90, email@example.com, 8-800-555-35-35."
pattern = r"[\d()-]+" # Ищем последовательности цифр, скобок и дефисов
phones = re.findall(pattern, text)
print(f"Найденные номера: {phones}")
# Найденные номера (упрощенно): ['7', '123', '456-78-90', '8-800-555-35-35']
pattern_words = r"\b\w+@\w+\.\w+\b|\b\w+\b" # Email ИЛИ слово
words_and_emails = re.findall(pattern_words, text)
print(f"Найденные слова и email: {words_and_emails}")
# Найденные слова и email: ['Контакты', '7', '123', '456', '78', '90', 'email@example.com', '8', '800', '555', '35', '35']
pattern = r"\d+"
text = "В нашем магазине 123 товара."
replaced_text = re.sub(pattern, "много", text)
print(replaced_text)
# В нашем магазине много товара.
text = "Цена: 500 руб. Скидка: 100 руб."
pattern = r"\d+" # Ищем числа
replacement = "XXX"
new_text = re.sub(pattern, replacement, text)
print(f"Замаскированный текст: {new_text}")
# Замаскированный текст: Цена: XXX руб. Скидка: XXX руб.
# Заменить только первое совпадение
new_text_first = re.sub(pattern, replacement, text, count=1)
print(f"Замаскировано только первое число: {new_text_first}")
# Замаскировано только первое число: Цена: XXX руб. Скидка: 100 руб.
text = "Товар А стоит 1500 руб., Товар Б - 2500 руб., доставка 300р."
pattern = r"\d+(?=\s*руб|\s*р)" # Число, за которым следуют пробелы (0+) и "руб" или "р"
prices = re.findall(pattern, text)
print(f"Найденные цены (только числа): {prices}")
# Найденные цены (только числа): ['1500', '2500', '300']
text = "Пишите на support@example.com или звоните @tech_support_bot"
pattern = r"(?<=@)\w+" # Слово (\w+), которому предшествует @
handles = re.findall(pattern, text)
print(f"Найденные 'хэндлы': {handles}")
# Найденные 'хэндлы': ['example', 'tech_support_bot']
text = "Номер: +7-916-123-45-67"
# Шаблон: +7, дефис (не захватываем), (код города 3 цифры - захватываем), остальное
pattern = r"(?:\+7-)(\d{3})-\d{3}-\d{2}-\d{2}"
match = re.search(pattern, text)
if match:
# group(0) - всё совпадение
print(f"Полное совпадение: {match.group(0)}")
# group(1) - первая (и единственная) захватывающая группа (\d{3})
print(f"Код города: {match.group(1)}")
else:
print("Номер не найден или формат неверный.")
# Полное совпадение: +7-916-123-45-67
# Код города: 916
def is_valid_ru_phone(phone):
# Шаблон: +7 или 8, потом необязательные пробелы/скобки/дефисы,
# 3 цифры, необязательные разделители, 3 цифры, разделители, 2 цифры, разделители, 2 цифры.
pattern = r"^(?:\+7|8)[\s(-]*\d{3}[\s)-]*\d{3}[\s-]*\d{2}[\s-]*\d{2}$"
return bool(re.match(pattern, phone))
print(f"+7 (916) 123-45-67: {is_valid_ru_phone('+7 (916) 123-45-67')}")
# True
print(f"8-926-9876543: {is_valid_ru_phone('8-926-9876543')}")
# True
print(f"89031112233: {is_valid_ru_phone('89031112233')}")
# True
print(f"7 123 456 78 90: {is_valid_ru_phone('7 123 456 78 90')}") # Неверный префикс
#False
print(f"911: {is_valid_ru_phone('911')}")
# False
def is_valid_email(email):
# Упрощенный шаблон: символы@символы.символы
pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
return bool(re.match(pattern, email))
print(f"test@example.com: {is_valid_email('test@example.com')}")
# True
print(f"мой.ящик+tag@домен.рф: {is_valid_email('мой.ящик+tag@домен.рф')}")
# True
print(f"просто текст: {is_valid_email('просто текст')}")
# False
print(f"test@example: {is_valid_email('test@example')}")
# False
log_line = "2023-10-27 15:30:01 INFO: Пользователь admin вошел с IP 192.168.1.101 успешно."
# Шаблон: граница слова, 1-3 цифры, точка, 1-3 цифры, точка, ... , граница слова
pattern = r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
ip_match = re.search(pattern, log_line)
if ip_match:
print(f"Найден IP-адрес: {ip_match.group()}")
else:
print("IP-адрес не найден.")
# Найден IP-адрес: 192.168.1.101
import time
texts = ["Номер 123", "Текст без цифр", "Еще 456 и 789"] * 10000
pattern_str = r"\d+"
# Без компиляции
start_time = time.time()
for text in texts:
re.search(pattern_str, text)
time_no_compile = time.time() - start_time
# С компиляцией
compiled_pattern = re.compile(pattern_str)
start_time = time.time()
for text in texts:
compiled_pattern.search(text)
time_with_compile = time.time() - start_time
print(f"Время без компиляции: {time_no_compile:.4f} сек")
print(f"Время с компиляцией: {time_with_compile:.4f} сек")
# Обычно время с компиляцией заметно меньше на больших объемах.
texts = ["abc123xyz", "123", "a123b", "x123y", "безномера", "123", "тест"] * 50000
# Менее эффективный шаблон
pattern1 = r".*123.*"
start_time = time.time()
for text in texts:
match = re.search(pattern1, text)
end_time = time.time()
time_with_less_efficient_pattern = end_time - start_time
# Более эффективный шаблон
pattern2 = r"\b123\b"
start_time = time.time()
for text in texts:
match = re.search(pattern2, text)
end_time = time.time()
time_with_more_efficient_pattern = end_time - start_time
print(f"Время с неэффективным шаблоном: {time_with_less_efficient_pattern:.3f} сек, время с эффективным шаблоном: {time_with_more_efficient_pattern:.3f} сек")
# На исполнее более эффективного шаблона нужно меньше времени
# Определяем шаблон regex без использования сырой строки
pattern_without_raw = "\d+"
# Определяем тот же шаблон regex, используя сырую строку
pattern_with_raw = r"\d+"
text = "123 456 789 012" * 3000000
# Поиск с использованием шаблона без сырой строки
start_time = time.time()
matches_without_raw = re.findall(pattern_without_raw, text)
end_time = time.time()
time_without_raw = end_time - start_time
# Поиск с использованием шаблона с сырой строкой
start_time = time.time()
matches_with_raw = re.findall(pattern_with_raw, text)
end_time = time.time()
time_with_raw = end_time - start_time
print(f"Время без сырой строки: {time_without_raw:.3f} сек")
print(f"Время с сырой строкой: {time_with_raw:.3f} сек")
# с raw-строкой будет точно быстрее
# Определяем шаблон regex для сопоставления адресов электронной почты
pattern_without_raw = "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"
text = "Свяжитесь с нами по адресу email@example.com или посетите наш сайт www.example.com"
# Пытаемся найти адреса электронной почты, используя шаблон без сырой строки
matches_without_raw = re.findall(pattern_without_raw, text)
print(f"Совпадения без сырой строки: {matches_without_raw}")
# []
pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"