Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3

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

28.08.2012, 02:12. Показов 1205. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую.

Свою молодость провел бурно, на программирование времени не осталось. Печально. Прошу помощи:

Есть текстовый файл с записями вида:

901 1800000 1899999
901 7000000 7299999

Скрывать не буду - это телефонные коды, разбитые по регионам и принадлежащие тому или иному оператору связи. Есть задача - привести все это к виду "регулярного выражения" (надеюсь все знают что это такое?). Т.е. программка читает файлик, сравнивает 2 и 3 столбцы и на выходе выдает что-то вроде этого (комментарии как пояснение):

901 1800000 1899999 ^90118\d{5}$ //первые 5 цифр статичные, остальные 5 - любые (\d{5}).
901 7000000 7299999 ^9017[0-2]\d{5}$ //4 начальных цифры статичные, 5 цифра - 0 или 1 или 2, остальные 5 цифр - любые(\d{5}).

Думаю задача довольно интересная для тех кто учится писать на C, C++ и т.п. (в памяти всплывают слова лектора о том, что работа со строками и подстроками - важный аспект программирования).
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.08.2012, 02:12
Ответы с готовыми решениями:

Регулярные выражения
Привет помогите составить регулярное выражение, чтобы парсить такую строку: , , результатом должно быть: a hello world any ...

Регулярные выражения
Как из этой строки вытянуть png с помощью регулярки, кроме png может быть другой тип, "image/" всегда неизменна HTTP/1.1...

Регулярные выражения с++11
Просветите, пожалуйста, как из следующей строки "123<tag>456</tag>789<tag>987</tag>654321" с помощью регулярного выражения напечатать...

7
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
28.08.2012, 03:12
Labus, Ну если простые регексы - то легко. А если сложные... Ну как бэ каждое выражение можно выразить разными регексами по большому счету. А чего самому-то не сделать?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.08.2012, 03:45
Нифига не понял, программа должна составлять регулярное выражение на основе файла с номерами?
Или просто делать выборку согласно заданной регулярки?
0
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3
28.08.2012, 12:38  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Нифига не понял, программа должна составлять регулярное выражение на основе файла с номерами?
Или просто делать выборку согласно заданной регулярки?

программа должна составлять регулярное выражение на основе файла с номерами:

Т.е. из записи вида 901 1800000 1899999 должна получать на выходе ^90118\d{5}$

^ - начало строки
$ - конец строки
\d{n} - любые n целых цифр ( \d{5} = последовательность из 5 любых целых от 0 до 9 цифр).
[0-2] - любая цифра из набора 0 1 2.
0
 Аватар для igorrr37
2878 / 2025 / 992
Регистрация: 21.12.2010
Сообщений: 3,779
Записей в блоге: 9
28.08.2012, 12:54
префикс 901 у обоих номеров одинаковый?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
//#include <boost/regex.hpp>
 
/*
    901 1800000 1899999      ^90118\d{5}$
    901 7000000 7299999      ^9017[0-2]\d{5}$
*/
 
int main()
{
    std::fstream ifs("in.txt", std::ios::in);
    if(ifs.is_open())
    {
        std::string s1, s2, res;
        while(std::getline(ifs, s1))
        {
            //if(boost::regex_match(s1, boost::regex(" *\\d{3} +\\d{7} +\\d{7} *"))) // проверка строки на валидность
            //{
                std::stringstream ss(s1);
                ss >> s1;
                res += ("^" + s1);
                ss >> s1 >> s2;
                ss.clear();
                ss.str("");
                std::string::const_iterator cits1(s1.begin()), cits1End(s1.cend()), cits2(s2.begin());
                for(; cits1 != cits1End; ++cits1, ++cits2)
                {
                    if(*cits1 == *cits2)
                    {
                        res += *cits1;
                    }
                    else if(*cits1 != '0' || *cits2 != '9')
                    {
                        ss << '[' << *cits1 << '-' << *cits2 << ']';
                        res += ss.str();
                        ss.str("");
                    }
                    else
                    {
                        res += "\\d";
 
                    }
                }
                res += '$';
                std::size_t cntr;
                std::string::size_type ind, ind1;
                for(ind = 0; (ind = res.find("\\d", ind)) != std::string::npos; ind += 2) // заменяем последовательность из нескольких \d на \d{n}
                {
                    for(ind1 = ind + 2, cntr = 1; res.find("\\d", ind1) == ind1; ind1 += 2, ++cntr)
                        ;
                    if(ind1 != ind + 2)
                    {
                        ss << "\\d{" << ((ind1 - ind) / 2) << '}';
                        res.replace(ind, ind1 - ind, ss.str());
                        ss.str("");
                    }
                }
                std::cout << res << std::endl;
                res.clear();
            //}
            //else
                //std::cerr << "String:\n" << s1 << "\nis invalid" << std::endl;
        }
        ifs.close();
    }
    else
        std::cerr << "Unable to open file" << std::endl;
    return 0;
}
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
28.08.2012, 13:56
Окей, контрпример:
номера, начинающиеся на 901 700, могут дальше состоять только из чисел до 120000;
начинающиеся на 901 701 — до 140000;
и т. п.

Простыми регэкспами все случаи не покроешь.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.08.2012, 14:41
Цитата Сообщение от Labus Посмотреть сообщение
программа должна составлять регулярное выражение на основе файла с номерами:
Т.е. из записи вида 901 1800000 1899999 должна получать на выходе ^90118\d{5}$
^ - начало строки
$ - конец строки
\d{n} - любые n целых цифр ( \d{5} = последовательность из 5 любых целых от 0 до 9 цифр).
[0-2] - любая цифра из набора 0 1 2.
Т.е. один один одно выражение ?
0
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3
28.08.2012, 18:07  [ТС]
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Окей, контрпример:
номера, начинающиеся на 901 700, могут дальше состоять только из чисел до 120000;
начинающиеся на 901 701 — до 140000;
и т. п.

Простыми регэкспами все случаи не покроешь.

Я нигде не указывал ограничения в использовании регэкспов. Все что было выше - всего лишь пример.

Строки всегда одинаковой длины.

901 1800000 1899999
901 7000000 7299999

Что мешает сравнивать посимвольно и делать регэкспы для каждой цифры номера? Например если сравнить в 1 строке последние 5 цифр 2 и 3 столбца - видно, что это могут быть любые цифры в промежутке от 0 до 9 и их можно заменить на \d{5}, а во 2 строке 70 и 72 отличаются только 2 цифрой. Такие вещи заменять [0-2], оставшиеся 5 заменяем на \d{5}...


Хотя, наверное это все-таки сложно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.08.2012, 18:07
Помогаю со студенческими работами здесь

Регулярные выражения в g++
Привет всем! этот пример взял из http://www.cplusplus.com/reference/regex/regex_search/ и скомпилировал g++ . #include &lt;iostream&gt; ...

Регулярные выражения
Можете подсказать что это значит? &quot;Max-Forwards*(\d{3,}|7)&quot; я без понятия что это и откуда это( Добавлено через 4 минуты я уже...

Регулярные выражения
Стоит задача, проверить является ли вводимая строка заданной маской. Но маска(регулярное выражение тоже как я понял должно вводится со...

С++ и регулярные выражения
С++ и регулярные выражения - возможно ли ето? Какие есть библиотеки или что-то в етом роде?

Регулярные выражения
Может кто нибудь подсказать реализацию регулярных выражений на С/С++?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru