Rating@Mail.ru

Форум по операционной системе GNU/Linux и свободному программному обеспечению


Текущее время: 18 дек 2017, 12:08

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 14 сен 2016, 12:39 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Здесь вот онлайновый тестер регулярных выражений, который позволяет проверить результат сопоставления, без написания какого-либо программного кода и не используя никакие GNU утилиты: Regex Pal.
Очень удобно при отработке.


И ещё:
RegExrv2.1

И ещё:
0.3.1b built by gskinner.com

Но самое смешное, так это что регулярные выражения, сопоставляются в одном из таких онлайнов, а также grep, egrep и др. - не сопоставляются во всех остальных и наоборот. :-o :-(
В этом смысле показательна фраза (стр.12) из книги Майкла Фицджеральда:
Цитата:
Большинство из указанных реализаций регулярных выражений в чем-то сходны, а в чем-то различаются. Я не могу подробно обсудить все отличия в столь маленькой кни­
ге, но о многих расскажу. Любые попытки задокументировать все различия между все­ ми реализациями наверняка привели бы меня в больницу.

:lol:


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 18 ноя 2016, 23:11 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Сами регулярные выражения, перед их внесением в код C/C++ хорошо бы проверять (отлаживать) ... хотя бы просто потому, что регулярные выражения - уж точно "не фишка" C/C++, не самое сильное место этих языков.
Для этого хорошо бы иметь под рукой тестовый инструмент регулярных выражений.
Я предлагаю использовать в этом качестве sed - потоковый текстовый редактор.
И в упоминаемой там книге Краткий учебник по sed есть Глава 2 - вполне достаточное введение в технику регулярных выражений.


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 13 май 2017, 09:46 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Не прошло и пол-года, как возникла ещё раз оказия порепетировать с регулярными выражениями C++, в связи с вот этой проблемой: интерпретатор программного кода (на C++). Но с регулярными выражениями (на любом инструменте их использования: Perl, Python, Ruby, sed, awk, grep, egrep, ...) проблема состоит в том, что для синтаксиса регулярных выражений существует 10000000 стандартов граматики, и никогда не знаешь деталей того, который сейчас используешь.
Вот так же и с библиотекой regex C++:
- она новая, появилась только в стандарте C++11 (2011г.)
- нигде толком не описана (в деталях граматик)
- при создании объектов регулярных выражений можно указать константой в конструкторе 5 (как минимум) различающихся граматик:
Цитата:
basic Basic POSIX grammar
extended Extended POSIX grammar
awk Awk POSIX grammar
grep Grep POSIX grammar
egrep Egrep POSIX grammar

- мелкие детали того, что они понимают под каждой, нигде не описано. :-(

Хоть вот это ;-) : syntax specifications std::ECMAScript syntax
Цитата:
The following syntax is used to construct regex objects (or assign) that have selected ECMAScript as its grammar.


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 17:01 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Olej писал(а):
P.S. В приложении - все сразу показанные до сих пор примеры.

Дальнейшие редакции этого текста (дополнения, изменения, исправления, ...) см. здесь: Регулярные выражения C/C++

Регулярные выражения в С++ с блеском показали себя на 2-х проектах:
интерпретатор программного кода (на C++)
симулятор процессора
Особенно во 2-м!
Синтаксический разбор языка ассемблера, который мог бы делаться неделями или даже месяцами, был прописан в 3 дня работы.


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 17:18 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Особенно во 2-м!
Синтаксический разбор языка ассемблера, который мог бы делаться неделями или даже месяцами, был прописан в 3 дня работы.

Но во всех задачах подбирать вид регулярного выражения - занятие тягомутное и трудоёмкое.
Чтоб его сделать простым и быстрым, сделано такое приложение regc.cc :
- считывает любое число строк-патернов (регулярных шаблонов) из отдельного файла, расширения .pat
- потом в диалоге прогоняющем все вводимые строки на результат отождествления c этими патернами.
Код:
#include <iostream>
#include <fstream>
#include <regex>
using namespace std;

inline regex pattern( const string& r ) {
   //   try { return regex( r ); }                     // с учётом регистра
   try { return regex( r, regex_constants::icase ); }  // без учёта регистра
   catch( regex_error& e ) {                           // ошибка записи регулярного выражения
      cerr << "синтаксис регулярного выражения:\t" << r << endl;
      exit( 3 );
   }
}
// static constexpr flag_type basic = regex_constants::basic;
// static constexpr flag_type extended = regex_constants::extended;
// static constexpr flag_type awk = regex_constants::awk;
// static constexpr flag_type grep = regex_constants::grep;

int test_table( int p, char* fname[] ) {
   while( --p ) {
      ifstream fin;
      fin.open( fname[ p ] );
      if( !fin ) break;
      fin.close();
   }
   return p;
}

vector<regex> load_table( int p, char* fname[] ) {
   vector<regex> vr;
   int n = 1;
   while( --p ) {
      ifstream fin;
      string cur;
      fin.open( fname[ p ] );
      while( true ) {             
         getline( fin, cur );
         if( fin.eof() ) break;                        // EOF
         if( '#' == cur[ 0 ] ) continue;               // комментарий
         if( !cur.length() ) continue;                 // пустая строка
         try {
            regex rc = regex( cur );
            vr.push_back( rc );
            cout << "#" << n++ << ":\t" << cur << endl;
         }
         catch( regex_error& e ) {                     // ошибка трансляции регулярного выражения
            cout << "ошибка:\t" << cur << endl;
         }
      }
      fin.close();
   }     
   cout << "-------------------------------------------" << endl;
   return vr;
}

int main( int argc, char *argv[] ) {
   if( argc < 2 ) {
       cout << "не заданы файлы щаблонов?" << endl;
       return 1;
   }
   int n = test_table( argc, argv );
   if( n ) {
      cout << "файл шаблонов не найден: " << argv[ n ] << endl;     
      return 2;
   }
   vector<regex> r = load_table( argc, argv );
   smatch m;
   while( true ) {
      cout << "> ";
      string cur;
      getline( cin, cur );
      if( cin.eof() ) {
         cout << endl;
         return 0;
      }
      if( cur == "!" || cur == "~" ) {
         r = load_table( argc, argv );
         continue;
      }
      n = 1;
      for( auto &pt : r ) {
         if( regex_match( cur, m, pt ) ) {
            cout << "#" << n << " [" << m.size() << "]: " << m[ 0 ].str() << " => " << endl;
            for( unsigned i = 1; i < m.size(); i++ )
               cout << i << ": [" << m[ i ].str() << "] <" << m.position( i ) << ":"
                    << m.length( i ) << ">" << endl;
         }
         n++;
      }
   }
}


Вложения:
regs.218.tgz [2.13 КБ]
Скачиваний: 0
Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 17:27 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Но во всех задачах подбирать вид регулярного выражения - занятие тягомутное и трудоёмкое.
Чтоб его сделать простым и быстрым, сделано такое приложение regc.cc :
- считывает любое число строк-патернов (регулярных шаблонов) из отдельного файла, расширения .pat
- потом в диалоге прогоняющем все вводимые строки на результат отождествления c этими патернами.

Выглядеть это может примерно так ... чтобы долго не объяснять:
Код:
[olej@dell 3]$ ./regs cmd.pat
#1:     ^\s*(nop)\s*$
#2:     ^\s*(halt)\s*$
#3:     ^\s*(rrmovl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#4:     ^\s*(irmovl)\s+(\w+|\$[\+|\-]?[0-9]+|\$0x[0-9|a-f]+)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#5:     ^\s*(rmmovl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*([\+|\-]?[0-9]+|0x[0-9|a-f]+)*\s*\(\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*\)\s*$
#6:     ^\s*(mrmovl)\s+([\+|\-]?[0-9]+|0x[0-9|a-f]+)*\s*\(\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*\)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#7:     ^\s*(addl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#8:     ^\s*(subl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#9:     ^\s*(andl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#10:    ^\s*(xorl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*,\s*%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#11:    ^\s*(jmp)\s+(\w+)\s*$
#12:    ^\s*(jle)\s+(\w+)\s*$
#13:    ^\s*(jl)\s+(\w+)\s*$
#14:    ^\s*(je)\s+(\w+)\s*$
#15:    ^\s*(jne)\s+(\w+)\s*$
#16:    ^\s*(jge)\s+(\w+)\s*$
#17:    ^\s*(jg)\s+(\w+)\s*$
#18:    ^\s*(call)\s+(\w+)\s*$
#19:    ^\s*(ret)\s*$
#20:    ^\s*(pushl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
#21:    ^\s*(popl)\s+%e(ax|cx|dx|bx|sp|bp|si|di)\s*$
-------------------------------------------
> nop
#1 [2]: nop =>
1: [nop] <0:3>
> halt
#2 [2]: halt =>
1: [halt] <0:4>
> rrmovl %eax , %ebx
#3 [4]: rrmovl %eax , %ebx =>
1: [rrmovl] <0:6>
2: [ax] <9:2>
3: [bx] <16:2>
> irmovl array , %edx
#4 [4]: irmovl array , %edx =>
1: [irmovl] <0:6>
2: [array] <7:5>
3: [dx] <17:2>
> irmovl $4 , %esi
#4 [4]: irmovl $4 , %esi =>
1: [irmovl] <0:6>
2: [$4] <7:2>
3: [si] <14:2>
> irmovl $-10 , %esi
#4 [4]: irmovl $-10 , %esi =>
1: [irmovl] <0:6>
2: [$-10] <7:4>
3: [si] <16:2>
> rmmovl  %ecx , -3(%ebx)
#5 [5]: rmmovl  %ecx , -3(%ebx) =>
1: [rmmovl] <0:6>
2: [cx] <10:2>
3: [-3] <15:2>
4: [bx] <20:2>
> rmmovl %esp, 0x12345 (%edx)
#5 [5]: rmmovl %esp, 0x12345 (%edx) =>
1: [rmmovl] <0:6>
2: [sp] <9:2>
3: [0x12345] <13:7>
4: [dx] <24:2>
> mrmovl (%edx), %eax
#6 [5]: mrmovl (%edx), %eax =>
1: [mrmovl] <0:6>
2: [] <19:0>
3: [dx] <10:2>
4: [ax] <17:2>
> mrmovl 8(%ebp), %edx
#6 [5]: mrmovl 8(%ebp), %edx =>
1: [mrmovl] <0:6>
2: [8] <7:1>
3: [bp] <11:2>
4: [dx] <18:2>
> mrmovl -12(%ebp), %edx
#6 [5]: mrmovl -12(%ebp), %edx =>
1: [mrmovl] <0:6>
2: [-12] <7:3>
3: [bp] <13:2>
4: [dx] <20:2>
> mrmovl 0xf012( %eax ) , %ebx
#6 [5]: mrmovl 0xf012( %eax ) , %ebx =>
1: [mrmovl] <0:6>
2: [0xf012] <7:6>
3: [ax] <17:2>
4: [bx] <26:2>
> addl %eax , %ebx
#7 [4]: addl %eax , %ebx =>
1: [addl] <0:4>
2: [ax] <7:2>
3: [bx] <14:2>
>   subl %eax , %ebx
#8 [4]:   subl %eax , %ebx =>
1: [subl] <2:4>
2: [ax] <9:2>
3: [bx] <16:2>
>   andl %eax , %ebx
#9 [4]:   andl %eax , %ebx =>
1: [andl] <2:4>
2: [ax] <9:2>
3: [bx] <16:2>
>  xorl %eax , %ebx
#10 [4]:  xorl %eax , %ebx =>
1: [xorl] <1:4>
2: [ax] <8:2>
3: [bx] <15:2>
>  jmp yyyy
#11 [3]:  jmp yyyy =>
1: [jmp] <1:3>
2: [yyyy] <5:4>
>  jle yyyy
#12 [3]:  jle yyyy =>
1: [jle] <1:3>
2: [yyyy] <5:4>
> jl yyyy
#13 [3]: jl yyyy =>
1: [jl] <0:2>
2: [yyyy] <3:4>
> je yyyy
#14 [3]: je yyyy =>
1: [je] <0:2>
2: [yyyy] <3:4>
> jne yyyy
#15 [3]: jne yyyy =>
1: [jne] <0:3>
2: [yyyy] <4:4>
> jge yyyy
#16 [3]: jge yyyy =>
1: [jge] <0:3>
2: [yyyy] <4:4>
> jg yyyy
#17 [3]: jg yyyy =>
1: [jg] <0:2>
2: [yyyy] <3:4>
>   call xxxx
#18 [3]:   call xxxx =>
1: [call] <2:4>
2: [xxxx] <7:4>
>   ret
#19 [2]:   ret =>
1: [ret] <2:3>
>  pushl %ebp
#20 [3]:  pushl %ebp =>
1: [pushl] <1:5>
2: [bp] <9:2>
>  popl %ebp
#21 [3]:  popl %ebp =>
1: [popl] <1:4>
2: [bp] <8:2>
> ^C

Всё должно быть понятно!


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 18:11 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Вопрос (задают!):
- почему сами строки регулярных выражений в примерах кода C++ записываем так ( R"(...)" ) :?: :
Код:
R"(^\s*(.align)\s+(1|2|4|8|16|32)\s*$)"


Ответ состоит в том, что в записи C/C++ (по синтаксису строк) экранирующий символ '\' нужно бы записывать 2 раза подряд: "\\d".
Например, для показанной выше строки шаблона: R"(^\s*(.align)\s+(1|2|4|8|16|32)\s*$)" - полностью эквивалент можно записать и так (сравнивайте):
Код:
"^\\s*(.align)\\s+(1|2|4|8|16|32)\\s*$"

Но при большом числе '\' в строке шаблона (а их всегда много) такая запись совсем не читабельная.

Это всё касается так называемого std::ECMAScript синтаксиса записи регулярных выражений.
Про это (и про синтаксис шаблонов ECMAScript) можете почитать здесь.
В <regex> можно изменять используемый синтаксис ... варианты:
Код:
string r = "...";            // шаблон
regex R = regex( r );  // по умолчанию, ECMAScript
regex R = regex( r, regex_constants::icase ); // без учёта регистра
// static constexpr flag_type basic = regex_constants::basic; // варианты синтаксиса:
// static constexpr flag_type extended = regex_constants::extended;
// static constexpr flag_type awk = regex_constants::awk;
// static constexpr flag_type grep = regex_constants::grep;


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 20:52 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Чтоб его сделать простым и быстрым, сделано такое приложение regc.cc :
- считывает любое число строк-патернов (регулярных шаблонов) из отдельного файла, расширения .pat
- потом в диалоге прогоняющем все вводимые строки на результат отождествления c этими патернами.

Ещё для тестирования регулярных выражений оказываются сильно полезны онлайн сервисы:

- https://regexr.ru/
Вложение:
r1.png
r1.png [ 160.05 КБ | Просмотров: 7 ]


- https://regexr.com/
Вложение:
r2.png
r2.png [ 241.55 КБ | Просмотров: 7 ]


Вернуться к началу
 Профиль Отправить личное сообщение  
 
 Заголовок сообщения: Re: регулярные выражения в C/C++
Непрочитанное сообщениеДобавлено: 12 дек 2017, 23:34 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 10265
Откуда: Харьков
Olej писал(а):
Это всё касается так называемого std::ECMAScript синтаксиса записи регулярных выражений.
Про это (и про синтаксис шаблонов ECMAScript) можете почитать здесь.

Эта ссылка, кстати, является вполне достаточной справочной страницей по std::ECMAScript syntax, вполне достаточной для написания собственных патернов синтаксического разбора:
Цитата:
ECMAScript regular expressions pattern syntax
...
Special pattern characters
...
Quantifiers
...

Groups
(subpattern) Group Creates a backreference.
(?:subpattern) Passive group Does not create a backreference.

Assertions
...
Alternatives
...
Character classes
...
[:xdigit:] hexadecimal digit character isxdigit
...

Ну, и ещё вот это - public member function <regex>
std::regex_traits::lookup_classname:
Цитата:
...
alpha alphabetic character isalpha
blank blank character isblank
cntrl control character iscntrl
digit decimal digit character isdigit
graph character with graphical representation isgraph
lower lowercase letter islower
print printable character isprint
punct punctuation mark character ispunct
space whitespace character isspace
upper uppercase letter isupper
xdigit hexadecimal digit character isxdigit
...


Вернуться к началу
 Профиль Отправить личное сообщение  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB
[ Time : 0.282s | 19 Queries | GZIP : On ]