Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Labus
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3
#1

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

28.08.2012, 02:12. Просмотров 591. Ответов 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++ и т.п. (в памяти всплывают слова лектора о том, что работа со строками и подстроками - важный аспект программирования).
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.08.2012, 02:12     Делаем регулярные выражения
Посмотрите здесь:

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

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

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

Регулярные выражения - C++
Ребят, у меня тут проблемы. В файле input.txt есть строчки, в которых нужно найти вес, т.е., например, 221 kg, 45g и отправить их в аутпут....

Регулярные выражения - C++
Доброй ночи! Использую вот такой код void INITDIALOG(void* p){ char* bufer = new char; server.GetLocList(bufer); char * t =...

Регулярные выражения - C++
Здравствуйте, Надо заменить в тексте номер телефона формата (012) 345-67-89 на +380 12 345 67 89. Помогите, пожалуйста, как должны...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
28.08.2012, 03:12     Делаем регулярные выражения #2
Labus, Ну если простые регексы - то легко. А если сложные... Ну как бэ каждое выражение можно выразить разными регексами по большому счету. А чего самому-то не сделать?
Avazart
Эксперт С++
7122 / 5299 / 273
Регистрация: 10.12.2010
Сообщений: 23,454
Записей в блоге: 17
28.08.2012, 03:45     Делаем регулярные выражения #3
Нифига не понял, программа должна составлять регулярное выражение на основе файла с номерами?
Или просто делать выборку согласно заданной регулярки?
Labus
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3
28.08.2012, 12:38  [ТС]     Делаем регулярные выражения #4
Цитата Сообщение от Avazart Посмотреть сообщение
Нифига не понял, программа должна составлять регулярное выражение на основе файла с номерами?
Или просто делать выборку согласно заданной регулярки?

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

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

^ - начало строки
$ - конец строки
\d{n} - любые n целых цифр ( \d{5} = последовательность из 5 любых целых от 0 до 9 цифр).
[0-2] - любая цифра из набора 0 1 2.
igorrr37
1644 / 1272 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
28.08.2012, 12:54     Делаем регулярные выражения #5
префикс 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;
}
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
28.08.2012, 13:56     Делаем регулярные выражения #6
Окей, контрпример:
номера, начинающиеся на 901 700, могут дальше состоять только из чисел до 120000;
начинающиеся на 901 701 — до 140000;
и т. п.

Простыми регэкспами все случаи не покроешь.
Avazart
Эксперт С++
7122 / 5299 / 273
Регистрация: 10.12.2010
Сообщений: 23,454
Записей в блоге: 17
28.08.2012, 14:41     Делаем регулярные выражения #7
Цитата Сообщение от Labus Посмотреть сообщение
программа должна составлять регулярное выражение на основе файла с номерами:
Т.е. из записи вида 901 1800000 1899999 должна получать на выходе ^90118\d{5}$
^ - начало строки
$ - конец строки
\d{n} - любые n целых цифр ( \d{5} = последовательность из 5 любых целых от 0 до 9 цифр).
[0-2] - любая цифра из набора 0 1 2.
Т.е. один один одно выражение ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2012, 18:07     Делаем регулярные выражения
Еще ссылки по теме:

Регулярные выражения. - C++
Здравствуйте всем! Имеется массив строк. Надо написать программу с функцией реализующей выявления соответствия между шаблоном допустим...

Регулярные выражения с++ - C++
Пользователь должен ввести строки: фамилию(первая буква должна быть заглавной), дату рождения(по форме аа.аа.аааа), состояние здоровья(good...

Регулярные выражения с++11 - C++
Просветите, пожалуйста, как из следующей строки &quot;123&lt;tag&gt;456&lt;/tag&gt;789&lt;tag&gt;987&lt;/tag&gt;654321&quot; с помощью регулярного выражения напечатать &quot;456...

Регулярные выражения - C++
Как записать строки у тегов &lt;c&gt;&lt;/c&gt; и &lt;v&gt;&lt;/v&gt;? &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt; &lt;worksheet...


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

Или воспользуйтесь поиском по форуму:
Labus
0 / 0 / 0
Регистрация: 28.08.2012
Сообщений: 3
28.08.2012, 18:07  [ТС]     Делаем регулярные выражения #8
Цитата Сообщение от ~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}...


Хотя, наверное это все-таки сложно.
Yandex
Объявления
28.08.2012, 18:07     Делаем регулярные выражения
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru