Регулярные выражения

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

hqhihi
Сообщения: 6
Зарегистрирован: 05 дек 2017, 02:13

05 дек 2017, 02:17

Привет всем!
Изучаю с++, начал тему регулярные выражения, и немного не понятна эта тема, решил для себя реализовать пару задач, одна из них это проверка мак адреса, то есть пользователь вводит что то похожее на мак адрес и ему должен прилететь ответ, правильно ли он написал его.
Мне бы объяснить немного, если можно код с комментариями, если не выйдет, то хотя бы мысль с чего и как начать.
Шаблон вроде как вот этот подойдет: ^([0-9A-Fa-f]{2}-){5}([0-9A-Fa-f]{2})$
Может кто додумать, как реализовать? Или если есть что то подобное на этом форуме, то ссылкой поделитесь пожалуйста.
Спасибо.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 дек 2017, 02:37

hqhihi писал(а):Привет всем!
Изучаю с++, начал тему регулярные выражения, и немного не понятна эта тема, решил для себя реализовать пару задач, одна из них это проверка мак адреса, то есть пользователь вводит что то похожее на мак адрес и ему должен прилететь ответ, правильно ли он написал его.
Мне бы объяснить немного, если можно код с комментариями, если не выйдет, то хотя бы мысль с чего и как начать.
Шаблон вроде как вот этот подойдет: ^([0-9A-Fa-f]{2}-){5}([0-9A-Fa-f]{2})$
Может кто додумать, как реализовать? Или если есть что то подобное на этом форуме, то ссылкой поделитесь пожалуйста.
Спасибо.
Это все классические алгоритмы которые были придуманы более 40 лет назад и с тех пор особо не изменялись. В данном случае это конечные автоматы. Есть два типа конечных автоматов - детерминированный и недетерминированный. Детерминированный идет циклом по регекспу и смотрит в текст, недетерминированный идет циклом по тексту и смотрит в регексп. Перловые - недетерминированные.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

05 дек 2017, 09:47

Какая стоит задача? Реализовать свою поддержку регулярных выражений (тренировочная цель) или достигнуть результата (коммерческая цель)?

Первый вариант осветил Absurd, так что отвечу по второму.

В С++, начиная с 11-го стандарта в наличие библиотечная поддержка регулярных выражений. Смотри класс regex, дальше двигайся по ссылкам. Если твой компилятор не поддерживает C++11, то твоё решение - это колыбель будущих стандартов библиотека boost. В ней класс доступен с тем именем и тем же набором методов. Отличие будет только в неймспейсе.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
hqhihi
Сообщения: 6
Зарегистрирован: 05 дек 2017, 02:13

05 дек 2017, 12:42

Romeo писал(а):Какая стоит задача? Реализовать свою поддержку регулярных выражений (тренировочная цель) или достигнуть результата (коммерческая цель)?

Первый вариант осветил Absurd, так что отвечу по второму.

В С++, начиная с 11-го стандарта в наличие библиотечная поддержка регулярных выражений. Смотри класс regex, дальше двигайся по ссылкам. Если твой компилятор не поддерживает C++11, то твоё решение - это колыбель будущих стандартов библиотека boost. В ней класс доступен с тем именем и тем же набором методов. Отличие будет только в неймспейсе.
Задача по сути не стоит, просто интересно выполнить это через регулярные выражения, представлю как задать условия и додумать это обычным методом, но через регулярные выражения я не пойму как это сделать, даже в шаблоне я не очень уверен.
Аватара пользователя
WinMain
Сообщения: 913
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

05 дек 2017, 14:58

Библиотеки регулярных выражений в том или ином виде сейчас есть практически во всех крупных С++ фрэймворках.
Вот несколько примеров: класс QRegExp в Qt и класс wxRegEx из wxWidgets.
Поэтому, если создаёшь приложение на базе какого-то крупного фрэймворка, то лучше сначала изучить его имеющиеся возможности, а так же средства стандартных библиотек самого языка программирования.
Для тех, кто программирует на Visual C++, там тоже есть своя небольшая поддержка регулярных выражений в библиотеке ATL (заголовочный файл atlrx.h), которая появилась ещё до принятия стандарта С++11.
hqhihi
Сообщения: 6
Зарегистрирован: 05 дек 2017, 02:13

05 дек 2017, 15:51

Romeo писал(а):Какая стоит задача? Реализовать свою поддержку регулярных выражений (тренировочная цель) или достигнуть результата (коммерческая цель)?

Первый вариант осветил Absurd, так что отвечу по второму.

В С++, начиная с 11-го стандарта в наличие библиотечная поддержка регулярных выражений. Смотри класс regex, дальше двигайся по ссылкам. Если твой компилятор не поддерживает C++11, то твоё решение - это колыбель будущих стандартов библиотека boost. В ней класс доступен с тем именем и тем же набором методов. Отличие будет только в неймспейсе.

По сути нет задачи конкретной, мне просто стало интересно, как это выглядят в коде, без регулярных выражений, я примерно представляю как это реализовать, с ними не совсем, я в шаблоне толком не уверен, хотя он должен быть верным, что выше давал.
hqhihi
Сообщения: 6
Зарегистрирован: 05 дек 2017, 02:13

05 дек 2017, 15:55

По сути нет конкретной задачи, мне для себя хотелось бы посмотреть на код или примерный код, я представляю как это реализовать без регулярных выражений, но с ними не получается, я выше шаблон написал, и то не уверен в его правильности.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 дек 2017, 03:12

hqhihi писал(а):По сути нет конкретной задачи, мне для себя хотелось бы посмотреть на код или примерный код, я представляю как это реализовать без регулярных выражений, но с ними не получается, я выше шаблон написал, и то не уверен в его правильности.
А в чем проблема? Чего конкретно не получается?

Код: Выделить всё

 
#include <iostream>
#include <sstream>
#include <regex>

int main()
{
	std::cout << "Enter string :";
	std::string str;
	std::getline(std::cin, str);
	if (std::regex_match(str, std::regex(R"(^([0-9A-Fa-f]{2}-){5}([0-9A-Fa-f]{2})$)"))) {
		std::cout << "\nString looks like MAC";
	} else { 
		std::cout << "\nString doesn't look like MAC";
	}
    return 0;
}
2B OR NOT(2B) = FF
hqhihi
Сообщения: 6
Зарегистрирован: 05 дек 2017, 02:13

06 дек 2017, 11:22

Absurd писал(а):А в чем проблема? Чего конкретно не получается?

Код: Выделить всё

 
#include <iostream>
#include <sstream>
#include <regex>

int main()
{
	std::cout << "Enter string :";
	std::string str;
	std::getline(std::cin, str);
	if (std::regex_match(str, std::regex(R"(^([0-9A-Fa-f]{2}-){5}([0-9A-Fa-f]{2})$)"))) {
		std::cout << "\nString looks like MAC";
	} else { 
		std::cout << "\nString doesn't look like MAC";
	}
    return 0;
}
Этот шаблон и тот что выше, они одинаковы, как я понимаю? И если я ввиду regex_search вместо match, то он все ровно проверяет, то получается разницы нет? Спасибо
"[0-9a-f]{2}-[0-9a-f]{2}"
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 дек 2017, 11:49

hqhihi писал(а):Этот шаблон и тот что выше, они одинаковы, как я понимаю?

Ну да, я просто скопипастил ваш регексп. R"(...)" это сравнительно новая конструкция (С++11 или 14) для "сырых" ("raw") строк С++, которые никак не обрабатываются компилятором. Для регекспов лучше использовать именно такие, поскольку язык регекспов активно использует символ '\', а это служебный символ во могих языках включая С++.
hqhihi писал(а): И если я ввиду regex_search вместо match, то он все ровно проверяет, то получается разницы нет? Спасибо
regex_search возвращает true если в исходной строке есть хотябы одно вхождение регекспа, regex_match проверяет соответствие строки регексу целиком.
2B OR NOT(2B) = FF
Ответить