Kibor |
Отправлено: 25 Сентября, 2018 - 03:14:54
|
Эксперт
Просматривает форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Символ ^ является символом экранирования в Кибор
Для использования в регулярном выражение символа ^ его необходимо заэкранировать им же самим.
То есть если необходимо использовать ^ и после него идет один из спецсимволов необходимо писать ^^
Если к примеру в регулярном выражение идет часть инструкции
\"
надо писать
\^"
Экранировать " отдельно для кода Кибор
Список символов которые экранируются:
Цитата: ^r - Вставляет символ \r 10. Возврат каретки в начало строки.
^n - Вставляет символ \n 13. Новая строка.
^t - Горизонтальная табуляция.
^v - Вертикальная табуляция.
^' - Апостроф (одинарные кавычки)
^" - Двойные кавычки
^x - Указывает что далее идет символ в 16 ричной системе. ^x41 = символ A.
^/ - Позволяет разделить // в тексте не прибегая к разрывам строки. /^/ выведет //
^* - Позволяет разделить начало комментирования /* в тексте. /^* выведет /*
^^ - Если необходимо вывести символ ^, а после него стоит один из управляющих символов, то можно ^ заэкранировать им же самим. ^^n выведет текст ^n
regexsearch - Ищет в тексте участок по шаблону регулярного выражения.
regexreplace - Ищет в тексте участок по шаблону регулярного выражения и заменяет его на указанный текст.
regexstart - Узнает стартовую позицию найденного фрагмента. Работает только с regexsearch. Использовать данную функцию можно только после вызова regexsearch
regexend - Узнает финишную позицию найденного фрагмента. Работает только с regexsearch. Использовать данную функцию можно только после вызова regexsearch
Подробный синтаксис и интерактивные примеры, где можно настроить и проверить выражение
Синтаксис:
regexsearch вызывается с разным количеством параметров.
Первый вызов идет такой:
CODE:regexsearch(1, #P[0], T, R);
или с флагами
CODE:regexsearch(1, #P[0], T, R, IGNORECASE | SINGLELINE | MULTILINE | GLOBAL | RIGHTTOLEFT | EXTENDED);
Первый параметр - желаемое количество найденных фрагментов. При -1 ищутся все.
Второй - Указатель на string или массив string (если будет искаться более одного), в который запишется найденный фрагмент.
Третий - Строка string, в которой находится текст в котором ищем.
Четвертый - Строка string регулярного выражения.
Пятый необязательный - Один или более флагов режима работы.
Другой вариант возможен с поиском в массиве char. Пример:
CODE:char T[1000];//Тут текст в котором ищем
int N=55;//С какого символа ищем
regexsearch(1, #P, #T[N], R);
Последующие вызовы, если мы не искали при первом вызове все вхождения, идет с двумя параметрами.
CODE:regexsearch(-1, #P[0]);
Первый параметр - желаемое количество найденных фрагментов. При -1 ищутся все.
Второй - Указатель на string или массив string (если будет искаться более одного), в который запишется найденный фрагмент.
Поиск продолжается в том тексте, в котором искали при вызове первой функции, с позиции последнего найденного, с регулярным выражение указанном при вызове первой функции.
При каждом последующем вызове будет искаться следующий фрагмент.
Или с тремя параметрами
CODE:regexsearch(-1, #P[0], R);
Первый - Сколько искать, или -1 если искать все
Второй - Указатель на string или массив string, в который запишутся найденные фрагменты текста
Третий - НОВАЯ Строка регулярного выражения
Поиск продолжается в том тексте, в котором искали при вызове первой функции, с позиции последнего найденного, но с новым регулярным выражением.
Для всех вариантов функций возможно указывать свои флаги.
Функция regexreplace возвращает 1 если была замена или 0 если не было.
Пример
CODE:string P[50];
string T="Сначала ищем числа -222+ или -555+, затем продолжаем числа -1111+ и " + "еще есть число -1212+ и -потом+ текст и еще -один+ текст"; // строка, в которой ищем
string R="(?<=-)[0-9]+(?=+)";
messagebox (T);
//Ищем 2 числа
int k=regexsearch(2, #P[0], T, R);
for (int n=0; n<k; n++)
{
messagebox (P[n]+" 0 "+format(regexstart(n)));
}
//Продолжаем доискивать все оставшиеся числа с последнего найденного места по старому регулярному выражению
k=regexsearch(-1, #P[0]);
for (n=0; n<k; n++)
{
messagebox (P[n]+" 1 "+format(regexstart(n)));
}
//Начинаем искать текст с новым регулярным с последнего найденного места
R="(?<=-)(.*?)(?=+)";
k=regexsearch(-1, #P[0], R);
for (n=0; n<k; n++)
{
messagebox (P[n]+" 2 "+format(regexstart(n)));
}
Функция regexsearch возвращает количество найденных фрагментов или 0 если не найдено.
==================================================
regexreplace так же вызывается с разным количеством параметров.
Первый вызов идет такой:
CODE:regexreplace(-1, #P, T, R, M);
или с флагами
CODE:regexreplace(-1, #P, T, R, M, IGNORECASE | SINGLELINE | MULTILINE | GLOBAL | RIGHTTOLEFT | EXTENDED);
Первый параметр - желаемое количество заменяемых фрагментов. При -1 заменяет все.
Второй - Указатель на string, в который запишется измененный текст.
Третий - Строка string, в которой находится исходный текст в котором заменяем. Этот текст остается без изменений
Четвертый - Строка string регулярного выражения, фрагмент которого в тексте будет заменен.
Пятый - Строка string, в которой текст на который будет заменен.
Шестой необязательный - Один или более флагов режима работы.
Если нет необходимости сохранять исходный текст, можно в качестве второго и третьего параметра использовать одну и ту же переменную. Тогда измененный текст перезапишется в исходник.
Последующие вызовы, если мы не заменяли все при первом вызове все вхождения, идет с двумя параметрами.
CODE:regexreplace(2, #P);
Первый - Сколько искать, или -1 если искать все
Второй - Указатель на string в который запишутся найденные фрагменты текста
Поиск продолжается в том тексте, в котором искали при вызове первой функции и с тем же регулярным выражением.
При каждом последующем вызове будет заменяться следующий фрагмент.
=====================================
regexstart и regexend вызываются с разным количеством параметров, в зависимости от того как будут использоваться.
Один вызов:
CODE:regexstart(#Pos_start[0]);
Параметр - Указатель на int или массив int, в который запишутся стартовые позиции найденных фрагментов. Массив выделять не менее количества фрагментов.
Возвращает количество найденных фрагментов, как и regexsearch.
CODE:regexend(#Pos_end[0]);
Параметр - Указатель на int или массив int, в который запишутся финишные позиции найденных фрагментов. Массив выделять не менее количества фрагментов.
Возвращает количество найденных фрагментов, как и regexsearch.
Второй вызов используется если надо узнать позицию только одного выбранного фрагмента:
Параметр - число означающее позицию какого фрагмента надо узнать.
В данном примере узнаем стартовую позицию 3 элемента.
Возвращает позицию элемента или -1, если данного элемента нет.
Параметр - число означающее позицию какого фрагмента надо узнать.
В данном примере узнаем финишную позицию 3 элемента.
Возвращает позицию элемента или -1, если данного элемента нет.
Описание флагов
IGNORECASE
По умолчанию регулярное выражение чувствительно к регистру. Примените этот режим, чтобы не учитывать регистр. Но наборы символов всегда чувствительны к регистру.
SINGLELINE
По умолчанию точка может соответствовать любому символу, кроме новой строки (\n). Режим SINGLELINE позволит точке соответствовать любому символу.
MULTILINE
Измените "^" и "$" на соответствие началу или концу строки для соответствия началу или концу любой строки в любом месте строки.
SINGLELINE и MULTILINE не исключают друг друга. Они имеют разные функции в разных местах, поэтому их можно использовать вместе.
Утверждения '\A' и '\Z' используются для соответствия только началу и концу строки, независимо от того, указан ли флаг MULTILINE.
GLOBAL
GLOBAL действует только на \G. Он позволяет \G соответствовать окончанию последнего совпадения, когда много раз повторяется. Без флага GLOBAL \G не используется в шаблоне.
По умолчанию операция замены заменит все совпадения, если даже GLOBAL не указан. Если вы не хотите заменять все совпадения, вы можете указать, сколько раз.
RIGHTTOLEFT
Поиск и замена справа на лево.
EXTENDED
Игнорирует символы пробела в шаблоне и рассматривает символы от # до конца строки как примечание.
Примеры:
Поиск в массиве char по одному со смещение начала поиска
CODE:string P;
string S="<+11111>xx<-22222>www<+33333>xx<-44444>www<+55555>xx<-66666>";
char T[100];
strcpy(#T[0], S);
int N=0;
loop()
{
if (regexsearch(1, #P, #T[N], "(?<=<\+)(.+?)(?=>)")==0) break;
messagebox (P);
N=N+regexend(0);
if (regexsearch(1, #P, #T[N], "(?<=<-)(.+?)(?=>)")==0) break;
messagebox (P);
N=N+regexend(0);
}
Ищем по одному
CODE:string P;
string T="1 USD Курс Доллара 66,8932 0,516 66,3772^r^n1 " + "EUR Курс Евро 76,0576 0,8323 75,2253 Курс Гривны 0,0005"; // строка, в которой ищем
string R="Курс.*?(\d+[,.]\d+)";//регулярное выражение
if (regexsearch(1, #P, T, R)!=0)
{
messagebox (P);
while (regexsearch(1, #P)!=0)
{
messagebox (P);
}
}
Ищем все и пишем в массив
CODE:string P[10];
string T="1 USD Курс Доллара 66,8932 0,516 66,3772 ^r^n" + "1 EUR Курс Евро 76,0576 0,8323 75,2253 Курс Гривны 0,0005"; // строка, в которой ищем
string R="Курс.*?(\d+[,.]\d+)";//регулярное выражение
int k=regexsearch(-1, #P[0], T, R);
for (int n=0; n<k; n++)
{
messagebox (P[n]);
}
Разбить текст на слова
CODE:string Text="Ёлки мама? wWR Мыла>25+2-ю раму, рама-мыла. <ма=му!";
string P[100];
int r=regexsearch(100, #P[0], Text, "[\wа-яА-ЯёЁ]+|[:punct:]");
for (int n=0; n<r; n++)messagebox(P[n]);
Найти в строке текст между value" и </div>
CODE:string P;
string T="<div class=^"info-value^">Бла бла ла ла</div>"; // no?iea, a eioi?ie euai
string R="(?<=value\^">)"+"(.*)+(?=</div>)";//?aaoey?iia au?a?aiea.
if (regexsearch(1, #P, T, R)==1)messagebox (P );
Поиск числа между WR, но WR не выводится в результат
CODE:string P[10];
string T="WR555WR WRworldWR 777 нет WR222WR"; // строка, в которой ищем
string R="(?<=WR)[0-9]+(?=WR)";//регулярное выражение. WR не выводится в результат
int k=regexsearch(-1, #P[0], T, R);
for (int n=0; n<k; n++)
{
messagebox (P[n]);
}
Найдет test если после него есть bar или foo
CODE:string P;
string T="testbarfoo";
//string T="testfoobar";
string R="test(?=.*bar)(?=.*foo)";
if (regexsearch(1, #P, T, R)==1)messagebox (P);
Разные переменные для источника и приемника
CODE:string T="qwertАБВqwertАБВ"; // строка, в которой заменяем
string R="[А-Я]";//Что заменяем (регулярное выражение)
string M="ГаВ";//Чем заменяем
string P;//Сюда запишем измененный текст
int k=regexreplace(2, #P, T, R, M);
messagebox (k);
messagebox (P);
k=regexreplace(-1, #P);
messagebox (k);
messagebox (P);
Одна переменная для источника и приемника
CODE:string T="qwertАБВqwertАБВ"; // строка, в которой заменяем
string R="[А-Я]";//Что заменяем (регулярное выражение)
string M="ГаВ";//Чем заменяем
int k=regexreplace(2, #T, T, R, M);
messagebox (k);
messagebox (T);
k=regexreplace(-1, #T);
messagebox (k);
messagebox (T);
Замена чисел между WR
CODE:string T="WR555WR WRworldWR 777 df WR222WR"; // строка, в которой заменяем
string R="(?<=WR)[0-9]+(?=WR)";//регулярное выражение. WR не заменяется
string M="ГаВ";//Чем заменяем
int k=regexreplace(1, #T, T, R, M);
messagebox (k);
messagebox (T);
k=regexreplace(-1, #T);
messagebox (k);
messagebox (T);
Составить регулярное выражение, до найденного любые символы но не более 10 знаков
Регулярка, которая находит числа между
чи
и
еще
Но при условии что эти чи и еще удалены от искомого числа на не более 10 символов.
То есть между чи и числом могут быть любые символы, но не более 10
Зеленое что должно найтись, красное не должно.
Цитата: string P[10];
string T="какое то число +10.5 еще одно число 12.5 и еще число -15 и еще ну а вот то число не должны найти 25 еще не найдено"; // строка, в которой ищем
string R="(?<=чи(.){0,10})[+-]?\d+(\.\d+)?(?=(.){0,10}еще)";
int k=regexsearch(10, #P[0], T, R);
for (int n=0 ; n<k ; n++ )
{
messagebox (P[n]);
}
Удалить все пробелы при распознавание текста
CODE:readtext (NUM, #Text, 8, 1, -1, -1, -1, -1, -1, 0, -1, ZVx1, ZVy1, ZVx2, ZVy2, -1);
regexreplace(-1, #Text, Text, " ", "");
messagebox (Text);
Удалить все пробелы в начале строки
CODE:regexreplace(-1, #Text, Text, "^\s+", "");
Удалить все пробелы в конце строки
CODE:regexreplace(-1, #Text, Text, "\s+$", "");
Удалить все пробелы в начале и конце строки
CODE:regexreplace(-1, #Text, Text, "^\s+|\s+$", "");
Кириллица в латиницу и наоборот
CODE:string rus[74]={"Ї", "ї", "Ж", "ж", "Ц", "ц", "Ч", "ч", "Щ", "щ", "Ш", "ш", "ь", "Ь", "Ю", "ю", "Я", "я", "Ё", "ё", "Ы", "ы", "Ъ", "ъ", "А", "а", "Б", "б", "В", "в", "Г", "г", "Ґ", "ґ", "Д", "д", "Е", "е", "Є", "є", "З", "з", "И", "и", "І", "і", "Й", "й", "К", "к", "Л", "л", "М", "м", "Н", "н", "О", "о", "П", "п", "Р", "р", "С", "с", "Т", "т", "У", "у", "Ф", "ф", "Х", "х", "Э", "э"};
string eng[74]={"Yi", "yi", "Zh", "zh", "Ts", "ts", "Сh", "ch", "Shh", "shh", "Sh", "sh", "^'", "^'", "Yu", "yu","Ya", "ya", "Yo", "yo", "Y", "y", "", "", "A", "a", "B", "b", "V", "v", "G", "g", "G", "g", "D", "d", "E", "e", "E", "E", "Z", "z", "I", "i", "I", "I", "J", "j", "K", "k", "L", "l", "M", "m", "N", "n", "O", "o", "P", "p", "R", "r", "S", "s", "T", "t", "U", "u", "F", "f", "H", "h", "E", "e"};
string S="Иван Иваныч Иванов сидит дома без штанов. Вышел зайка на крыльцо почесать своё ухО. Хвать за ухо, нет ухА, так и Ёп... с крыльца.";
for (int n=0; n<74; n++)
{
regexreplace(-1, #S, S, rus[n], eng[n]);
}
messagebox (S);
//Преобразуем назад.
for (n=0; n<74; n++)
{
if (eng[n]!="")regexreplace(-1, #S, S, eng[n], rus[n]);
}
messagebox (S); |
|
|
Kibor |
Отправлено: 27 Сентября, 2018 - 08:37:39
|
Эксперт
Просматривает форум
Сообщений всего: 8217
Дата рег-ции: Март 2013
Откуда: Одесса
Репутация: 357
|
Добавил флаги
IGNORECASE
По умолчанию регулярное выражение чувствительно к регистру. Примените этот режим, чтобы не учитывать регистр. Но наборы символов всегда чувствительны к регистру.
SINGLELINE
По умолчанию точка может соответствовать любому символу, кроме новой строки (\n). Режим SINGLELINE позволит точке соответствовать любому символу.
MULTILINE
Измените "^" и "$" на соответствие началу или концу строки для соответствия началу или концу любой строки в любом месте строки.
SINGLELINE и MULTILINE не исключают друг друга. Они имеют разные функции в разных местах, поэтому их можно использовать вместе.
Утверждения '\A' и '\Z' используются для соответствия только началу и концу строки, независимо от того, указан ли флаг MULTILINE.
GLOBAL
GLOBAL действует только на \G. Он позволяет \G соответствовать окончанию последнего совпадения, когда много раз повторяется. Без флага GLOBAL \G не используется в шаблоне.
По умолчанию операция замены заменит все совпадения, если даже GLOBAL не указан. Если вы не хотите заменять все совпадения, вы можете указать, сколько раз.
RIGHTTOLEFT
Поиск и замена справа на лево.
EXTENDED
Игнорирует символы пробела в шаблоне и рассматривает символы от # до конца строки как примечание. |
|
|
Zireael |
Отправлено: 21 Октября, 2018 - 11:31:18
|
Эксперт
Покинул форум
Сообщений всего: 4465
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Многое зависит от корректности данных. Если в строке не будет ничего лишнего , то можно и так. Например, если могут быть числа, перед которыми нет числа в скобках, то лучше так:
CODE:string P[50];
string T="152211(50), 6666, 5663(60)"; // 6666 не запишется в массив, т. к. перед ним нет числа в скобках
string R="\d+(?=\()"; // число, перед которым есть скобка, скобка экранируется обратным слешем \(
string R2="(?<=\()\d+(?=\))"; // число между скобками
int te[50];
int te1[50];
int n, k;
k=regexsearch(-1, #P[0], T, R);
for (n=0; n<k; n++)
{
te[n]=formatsn(P[n]);
messagebox (te[n]);
}
k=regexsearch(-1, #P[0], T, R2);
for (n=0; n<k; n++)
{
te1[n]=formatsn(P[n]);
messagebox (te1[n]);
}
Если в строке могут быть пробелы, то это тоже надо учесть в регулярном выражении. |
|
|
Zireael |
Отправлено: 02 Декабря, 2018 - 14:06:28
|
Эксперт
Покинул форум
Сообщений всего: 4465
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Цитата: Если что не хватает - пишите.
CODE:string R="Курс.*?(\d+[,.]\d+)";
Должно возвращать только число, т. е. подгруппу в скобках. Без скобок - всю строку.
Добавить возможность возвращать результат в двухмерный стринг, если ищутся несколько подгрупп.
Например:
CODE:string arr[10][2]; // сюда записать результат
string s="Время 12:30, 14:25"; // строка, в которой надо найти время
string R="\d{2}:\d{2}"; // регулярное выражение вернёт всю захваченную строку, т. е. 12:30 и 14:25
string R2="(\d{2}):(\d{2})"; // а так, возвращать 12 в arr[0][0], 30 в arr[0][1]
// 14 в arr[1][0], 25 в arr[1][1]; |
|
|
Dantes3000 |
Отправлено: 03 Февраля, 2019 - 22:35:17
|
Эксперт
Покинул форум
Сообщений всего: 1489
Дата рег-ции: Июнь 2016
Репутация: 58
|
Уже какой раз мне нужны эти регулярные выражения, но никак не могу в них разобраться...Всё время приходится свой парсер делать, что проще.
Как правильно из строки
Цитата: a (1).jpg # 15:30 4.2.19 # Строчка 1 +formatic(13)+ Строчка 2. #
получить в массив string
a (1).jpg
15:30 4.2.19
Строчка 1 +formatic(13)+ Строчка 2. //тут без переноса
(Добавление)
Ужас, не смотреть, 18+ (Отобразить)
CODE:
string text="a (1).jpg "+formatic(35)+" 15:30 4.2.19 "+formatic(35)+" Строчка 1 +formatic(13)+ Строчка 2. "+formatic(35);
string name_img;
string time;
string description;
char ch[9999];
strcpy(#ch[0], text);
for(int k=0; k<size(text); k++)
{
if (ch[k]==" " && ch[k+1]==formatic(35) ) break; //получение имени
else name_img=name_img+ch[k];
}
messagebox("имя_картинки -"+name_img+"-");
int b=k+3;
for(k=0; k<size(text); k++)
{
if(ch[b+k]==" " && ch[b+k+1]==formatic(35)) break; //получение времени
else time=time+ch[b+k];
}
messagebox("время-"+time+"-");
b=b+k+3;
for(k=0; k<size(text); k++)
{
if(ch[b+k]==" " && ch[b+k+1]==formatic(35)) break; //получение описания
else description=description+ch[b+k];
}
messagebox("описание-"+description+"-");
|
|
|
|