С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
1

Применение регулярных выражений для парсинга email-ов получателей из emf-файла

16.06.2016, 13:52. Показов 3280. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите как применять регулярные выражения к нескольким строкам (заранее количество не известно)
Например есть текст:
C++
1
2
3
4
5
6
7
8
9
Если регулярное выражение используется для замены текста, то результатом работы будет новая текстовая строка,
Не нужная строка "текст", "Текст"...
представляющая из себя исходный текст, из которого удалены найденные подстроки (сопоставленные образцу), а вместо них подставлены строки замены (возможно, модифицированные запомненными при разборе группами символов из исходного 
нужная строка "текст2", "Текст2"...
какой-то текст "Текст2"
какой-то текст "текст2"
 
текста). Частным случаем модификации текста является удаление всех вхождений найденного образца — для чего строка замены указывается пустой.
Не нужная строка "текст3", "Текст3"...
Как не трогая остальные получить только текст2, Текст2
При этом заранее количество строк, которые будут содержать "Текст2" не известно.
Я определяю нужную строку ("нужная строка "текст2", "Текст2"...) используя Pos(), выбераю из нее первые текст2, а вот как разобрать следующие строки и вытащить из них остальные текст2?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.06.2016, 13:52
Ответы с готовыми решениями:

Применение регулярных выражений для фильтра тегов
Всем доброго дня! Мне нужно реализовать функцию, которая преобразует входной текст в безопасный...

Применение регулярных выражений
Имеется список listPet = ,] нужно анализировать числа и названия животных. Сейчас все это...

Применение регулярных выражений к файлу
Мне нужно осуществить поиск по текстовому файлу (этак 15000 слов), можно ли не создавая переменные...

Как оптимизировать применение регулярных выражений
Как оптимизировать следующий код? string a2 = Regex.Replace(x, p, @"$4",...

22
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
16.06.2016, 16:54 2
Непонятно, что в конечном итоге требуется. Зачем в данном случае что-то искать, когда искомый текст и так известен, это текст2

Более приближенно к реальности можно задать вопрос?
0
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
16.06.2016, 17:19  [ТС] 3
Цитата Сообщение от volvo Посмотреть сообщение
Непонятно, что в конечном итоге требуется. Зачем в данном случае что-то искать, когда искомый текст и так известен, это текст2
Более приближенно к реальности можно задать вопрос?
Приближенно к реальности - по прежнему разбираю eml-файл. Стоит задача получить конечного адресата, т.е. из строки To: спарсить адреса. В этой строке (и следом за ней) может быть сколько угодно адресов (рассылка, спам).
Т.е. выглядит это так:
C++
1
2
3
4
5
6
Много не нужного текста
To: не нужный текст <mail1@mail.ru>,
не нужный текст <mail2@mail.ru>,
не нужный текст <mail3@mail.ru>,
Ну и так далее не предсказуемое количество раз....
И далее опять не нужный текст
Собственно у меня получается прочитать первый адрес, но как обработать последующие, собрав их в одну строку через запятую...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
16.06.2016, 18:36 4
Грубо - вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    std::auto_ptr<TRegExpr>re(new TRegExpr);
    re->Expression = L"(<((\\w+@\\w+\\.\\w+)*)>)";
 
    re->Compile();
    std::auto_ptr<TStringList> lst(new TStringList);
    if (re->Exec(Memo4->Text)) // Отсюда я брал тот текст, который был приведен выше
    do
    {
         lst->Add(re->Match[1]);
    } while (re->ExecNext());
    ShowMessage(lst->CommaText);
}
Вот результат:

Применение регулярных выражений для парсинга email-ов получателей из emf-файла


Этого хотелось?
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
16.06.2016, 20:28  [ТС] 5
Цитата Сообщение от volvo Посмотреть сообщение
Этого хотелось?
Не совсем. Этот код будет обрабатывать весь текст и соответственно выберет и другие адреса, которые мне не нужны (например From: адрес@отправителя.ру, мне нужны только получатели).

Добавлено через 21 минуту
т.е.
C++
1
2
3
4
5
6
Много не нужного тут могут быть ненужные адреса <не@нужный.адрес>текста
To: не нужный текст <mail1@mail.ru>,
не нужный текст <mail2@mail.ru>,
не нужный текст <mail3@mail.ru>,
Ну и так далее не предсказуемое количество раз....
И далее опять не нужный текст
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
16.06.2016, 21:07 6
Блин. Ты можешь нормально дать текст и написать, что должно быть получено в результате? А то "не нужный текст, не нужный текст..." Ну не нужный - так не обрабатывай!
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
17.06.2016, 17:07  [ТС] 7
Цитата Сообщение от volvo Посмотреть сообщение
Блин. Ты можешь нормально дать текст и написать, что должно быть получено в результате? А то "не нужный текст, не нужный текст..." Ну не нужный - так не обрабатывай!
Вот текст письма:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Delivered-To: [email]test@mail.ru[/email]
Return-path: <return@mail.ru>
Received: from [126.15.19.116] (port=6010 helo=[192.168.1.113])
    by smtp22.mail.ru with esmtpa (envelope-from <return@mail.ru>)
    id 1bDcmY-0003Yh-Bq; Thu, 16 Jun 2016 22:16:50 +0300
To: =?UTF-8?B?0JDQvdC00YDQtdC5?= <test@mail.ru>, 
"Support" <shadow_test@mail.ru>,
 "OK.ru Customer Support" <logins@odnoklassniki.ru>
From: =?UTF-8?B?0KLQtdGB0YLQvtCy0L7QtSDRgdC+0L7QsdGJ0LXQvdC40LU=?= <return.ru>
Subject: =?UTF-8?B?0KLQtdGB0YLQvtCy0L7QtSDRgdC+0L7QsdGJ0LXQvdC40LU=?=
Message-ID: <5763420.1061203@mail.ru>
Date: Thu, 16 Jun 2016 22:16:48 +0300
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:38.0) Gecko/20100101
 Thunderbird/40.2.1
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
X-Mras: OK
 
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae sit ab, 
laudantium deserunt laborum magnam dolore optio ex iure mollitia eius 
c......
Из всего этого безобразия необходимо спарсить получателей, записать их в строку test@mail.ru, shadow_test@mail.ru, logins@odnoklassniki.ru
При этом получателей может быть сколько угодно. Письма формируются по разному, единственное за что можно зацепиться (как я думаю) это ключевое слово To:. Далее (как я размышляю) надо в цикле перебирать все последующие строки, пока в ней не перестанут встречаться e-mail адреса.

Добавлено через 15 часов 0 минут
Подниму. Актуально.

Добавлено через 3 часа 33 минуты
Близок к решению своей проблемы. Выбираю нужные адреса, но если адреса имеют вид rozalski.name@mail.ru, то они не выбираются.
Подскажите как переписать выражение
C++
1
L"(<((\\w+@\\w+\\.\\w+)*)>)"
чтобы в первой части могли быть любые символы, в частности точка, а также как выбирать адреса без треугольных скобок?
0
191 / 52 / 19
Регистрация: 18.02.2013
Сообщений: 508
Записей в блоге: 9
17.06.2016, 17:21 8
C++
1
<(([a-z0-9_-]+\\\.)*[a-z0-9_-]+@[a-z0-9_-]+(\\\.[a-z0-9_-]+)*\\\.[a-z]{2,6})>
Миниатюры
Применение регулярных выражений для парсинга email-ов получателей из emf-файла  
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
17.06.2016, 19:03  [ТС] 9
А как записать чтобы выбирал без этих <> скобок?
Да и где взять такой конструктор?
0
191 / 52 / 19
Регистрация: 18.02.2013
Сообщений: 508
Записей в блоге: 9
17.06.2016, 19:54 10
А разве
C++
1
lst->Add(re->Match[1]);
не вытаскивает адреса без скобок?
Цитата Сообщение от rozalski Посмотреть сообщение
Да и где взять такой конструктор?
http://regexr.com/v1/
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
17.06.2016, 20:22  [ТС] 11
Цитата Сообщение от Gdasar Посмотреть сообщение
не вытаскивает адреса без скобок?
К сожалению нет. Уголки остаются...
0
191 / 52 / 19
Регистрация: 18.02.2013
Сообщений: 508
Записей в блоге: 9
17.06.2016, 20:26 12
rozalski, ну поиграйся вот с этим:
C++
1
re->Match[1]
Поставь 0, 1, 2 и так далее и посмотри что будет выводить.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
17.06.2016, 22:01 13
rozalski, это двухэтапный процесс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    String email = L"(<[^>]*>)";
    String toAddresses;
 
    std::auto_ptr<TRegExpr>re(new TRegExpr);
    re->Expression = L"^To:(([^<]*(<[^>]*>))*\\r\\n)From:";
    re->ModifierM = true;
 
    if (re->Exec(Memo4->Text))
    {
        toAddresses = re->Match[1];
    }
 
    std::auto_ptr<TStringList>lst(new TStringList);
    // тут можно проверить, найдена ли строка toAddresses
    re->Expression = email;
    if (re->Exec(toAddresses))
        do
        {
            lst->Add(re->Match[1]);
        }
        while (re->ExecNext());
    ShowMessage(lst->CommaText);
выдает нужный тебе список...
0
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
18.06.2016, 11:36  [ТС] 14
Я вот до такого дописался :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(list->Strings[count_string].Pos("To")>0&&list->Strings[count_string].Pos("To")<2) {
re->Expression = L"<(([a-z0-9_-]+\\\.)*[a-z0-9_-]+@[a-z0-9_-]+(\\\.[a-z0-9_-]+)*\\\.[a-z]{2,6})>";
re->Compile();
metka:
if(re->Exec(list->Strings[count_string]))
    do  {
        flag=re->Match[0];
        if(flag!=""){
            ReadedTo+=flag+", ";
            count_string++;
            goto metka;
            }
        }
        while(re->ExecNext());
    }
......
ReadedTo=StringReplace(ReadedTo,"<","", TReplaceFlags()<<rfReplaceAll);
ReadedTo=StringReplace(ReadedTo,">","", TReplaceFlags()<<rfReplaceAll);
ReadedTo.Delete(ReadedTo.Length(),1);
ReadedTo.Delete(ReadedTo.Length(),1);
Вроде работает....

Добавлено через 13 часов 16 минут
Цитата Сообщение от volvo Посмотреть сообщение
выдает нужный тебе список...
К сожалению приведенный код не заработал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String email = L"(<[^>]*>)";
String toAddresses;
std::auto_ptr<TRegExpr>re(new TRegExpr);
re->Expression = L"^To:(([^<]*(<[^>]*>))*\\r\\n)From:";
re->ModifierM = true;
    if (re->Exec(list->Text))
    {
        toAddresses = re->Match[1]; // это условие не выполняется
    }
    std::auto_ptr<TStringList>lst(new TStringList);
    // тут можно проверить, найдена ли строка toAddresses
    re->Expression = email;
    if (re->Exec(toAddresses))
        do
        {
            lst->Add(re->Match[1]); // и это условие не выполняется
        }
        while (re->ExecNext());
    ShowMessage(lst->CommaText);   // в итоге получаю пустой список
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
18.06.2016, 11:52 15
Цитата Сообщение от rozalski Посмотреть сообщение
К сожалению приведенный код не заработал
"Бедному Ванечке всюду камушки" (С) "Народная мудрость"

Применение регулярных выражений для парсинга email-ов получателей из emf-файла


P.S. Я неработающих кодов не выкладываю. Проверяй содержимое list-а, мне про него ничего не известно. Откуда он взялся, как заполняется... А мне, если честно, надоело по кругу ходить. Что бы не сделал - тебе все не так. Больше дел у меня нет, что-ли, кроме как постоянные претензии выслушивать? От темы отписываюсь.
0
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
18.06.2016, 12:03  [ТС] 16
Цитата Сообщение от volvo Посмотреть сообщение
Что бы не сделал - тебе все не так.
Да я же без претензий, просто пытаюсь разобраться. В list читается текст из eml файла, там все хорошо.
Почему может не выполняться условие?
C++
1
2
3
4
if (re->Exec(list->Text))
    {
        toAddresses = re->Match[1]; // это условие не выполняется
    }
Если в тексте не обнаруживается строка необходимого формата?
0
191 / 52 / 19
Регистрация: 18.02.2013
Сообщений: 508
Записей в блоге: 9
18.06.2016, 13:49 17
Цитата Сообщение от rozalski Посмотреть сообщение
там все хорошо
а ты уверен, что чтение происходит корректно?

Добавлено через 48 секунд
Цитата Сообщение от rozalski Посмотреть сообщение
Если в тексте не обнаруживается строка
в строке(тексте) нет совпадений с регулярным выражением.
1
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32992 / 21298 / 8180
Регистрация: 22.10.2011
Сообщений: 36,593
Записей в блоге: 8
18.06.2016, 14:08 18
Цитата Сообщение от rozalski Посмотреть сообщение
В list читается текст из eml файла, там все хорошо.
Было бы хорошо - все бы работало:
Миниатюры
Применение регулярных выражений для парсинга email-ов получателей из emf-файла  
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
18.06.2016, 16:37  [ТС] 19
Приведенный выше код работает на вышеприведенном примере, тут все замечательно. Но письма имеют различную структуру, например вот письмо уведомление с форума:
Кликните здесь для просмотра всего текста
Delivered-To: anfx@mail.ru
Return-path: <>
Authentication-Results: mxs.mail.ru; spf=softfail (mx221.i.mail.ru: transitioning domain of cyberforum.ru does not designate 185.12.92.28 as permitted sender) smtp.mailfrom=admin@cyberforum.ru smtp.helo=cyberguru.ru
Received-SPF: softfail (mx221.i.mail.ru: transitioning domain of cyberforum.ru does not designate 185.12.92.28 as permitted sender) client-ip=185.12.92.28; envelope-from=admin@cyberforum.ru; helo=cyberguru.ru;
Received: from [185.12.92.28] (port=25255 helo=cyberguru.ru)
by mx221.i.mail.ru with esmtp (envelope-from <admin@cyberforum.ru>)
id 1bDx2n-0005TW-6s
for anfx@mail.ru; Fri, 17 Jun 2016 19:54:57 +0300
X-Mru-BL: 0:0
X-Mru-TLS: TLSv1:AES256-SHA
X-Mru-BadRcptsCount: 0
X-Mru-PTR: cyberforum.ru
X-Mru-NR: 1
X-Mru-RC: EU
Received: from cyberguru.ru (localhost [127.0.0.1])
by cyberguru.ru (8.14.7/8.14.7) with ESMTP id u5HGsvZK028213
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
for <anfx@mail.ru>; Fri, 17 Jun 2016 19:54:57 +0300 (MSK)
(envelope-from admin@cyberforum.ru)
Received: (from cyberforum@localhost)
by cyberguru.ru (8.14.7/8.14.7/Submit) id u5HGsvIl028212;
Fri, 17 Jun 2016 19:54:57 +0300 (MSK)
(envelope-from admin@cyberforum.ru)
Date: Fri, 17 Jun 2016 19:54:57 +0300 (MSK)
X-Authentication-Warning: cyberguru.ru: cyberforum set sender to admin@cyberforum.ru using -f
To: anfx@mail.ru
Subject: =?windows-1251?q?=CE=F2=E2=E5=F2_=E2_=F2=E5=EC=E5_=27RegExp_-_=ED=E0=E9=F2=E8_=EE=F8=E8=E1=EA=F3_=E2_=EA=EE=E4=E5=27?=
X-PHP-Script: www.cyberforum.ru/newreply.php for 85.143.12.218, 85.143.12.218
From: =?windows-1251?q?CyberForum=2Eru_-_=F4=EE=F0=F3=EC_=EF=F0=EE=E3=F0=E0=EC=EC=E8=F1=F2=EE=E2_=E8_=F1=E8=F1=E0=E4=EC= E8=ED=EE=E2?= <admin@cyberforum.ru>
Auto-Submitted: auto-generated
Message-ID: <20160617165457.a3c68f56e97e@www.cyberforum.ru>
MIME-Version: 1.0
Content-Type: text/plain; charset="windows-1251"
Content-Transfer-Encoding: 8bit
X-Priority: 3
X-Mailer: vBulletin Mail via PHP
X-DMARC-Policy: no
X-Mras: OK
X-Mru-Authenticated-Sender: admin@cyberforum.ru
X-Spam: undefined
X-Senderinfo: 38

Уважаемый(ая) rozalski,

Gdasar только что ответил в теме, на которую Вы подписались, - RegExp - найти ошибку в коде - в разделе C++ Builder CyberForum.ru - форум программистов и сисадминов.

Эта тема расположена по адресу:
https://www.cyberforum.ru/cpp-... -post.html

Текст сообщения:
***************
А разве
lst->Add(re->Match[1]);не вытаскивает адреса без скобок?
---Цитата (сообщение от rozalski)---
Да и где взять такой конструктор?
---Конец цитаты---
http://regexr.com/v1/
***************

Также могут быть и другие сообщения, но Вы не будете получать уведомления, пока снова не посетите форум.

С наилучшими пожеланиями,
CyberForum.ru - форум программистов и сисадминов

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Отказ от подписки:


Тут уже приведенный способ не срабатывает.
Ковыряюсь дальше...

Добавлено через 13 минут
Празмышляю вслух. Если утверждение:
Цитата Сообщение от Gdasar Посмотреть сообщение
Если в тексте не обнаруживается строка
в строке(тексте) нет совпадений с регулярным выражением.
верно, то мне просто необходимо перебирать все строки после встретившегося To и проверять попадаются ли там адреса e-mail, как только они перестали встречаться запоминать уже найденные и выходить... Помимо этого встречаются письма в которых в строке To нет адреса, но есть адреса в следующих строках. Так, на словах вроде ничего сложного....
0
191 / 52 / 19
Регистрация: 18.02.2013
Сообщений: 508
Записей в блоге: 9
18.06.2016, 17:23 20
rozalski, попробуй:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String toAddresses;
std::auto_ptr<TRegExpr>re(new TRegExpr);
re->Expression = L"^To:(.*?)From:";
re->ModifierM = true;
if (re->Exec(Memo1->Lines->Text))
{
   toAddresses = re->Match[1];
}
std::auto_ptr<TStringList>lst(new TStringList);
// тут можно проверить, найдена ли строка toAddresses
re->Expression = L"([a-z0-9_-]+\\\.)*[a-z0-9_-]+@[a-z0-9_-]+(\\\.[a-z0-9_-]+)*\\\.[a-z]{2,6}";
if (re->Exec(toAddresses))
do
{
   lst->Add(re->Match[0]);
}
while (re->ExecNext());
//ShowMessage(lst->CommaText);
Memo1->Lines->Text = lst->Text;
Выводит
Код
anfx@mail.ru
на втором тексте
и
Код
test@mail.ru
shadow_test@mail.ru
logins@odnoklassniki.ru
на первом
0
18.06.2016, 17:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.06.2016, 17:23
Помогаю со студенческими работами здесь

Парсинг файла с использованием регулярных выражений
Доброго времени суток уважаемые форумчане! Есть такая тема: нужно выдернуть из определенного...

Парсинг файла с применением регулярных выражений
Приветствую всех! Ребята, подскажите. Есть файл со следующим содержимым. Необходимо с помощью...

Задача по обработке файла с использованием регулярных выражений
Пытаюсь решить задачу: Задан log-file с описанием четырёхдневных курсов в следующем виде: ...

С помощью регулярных выражений осуществить очистку файла от тегов
Написать консольное приложение, принимающее на вход путь к файлу, содержащему xhtml разметку....


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru