Автоматизация и боты

 Помощь      Поиск      Пользователи
Сайт Кибор     Программируемый кликер Кибор     Видео обучение     Заказать бот

 Страниц (25): [1] 2 3 4 5 6 7 8 9 » В конец    

> Описание: Поиск и замена текста по шаблонам регулярных выражений
Kibor
Отправлено: 25 Сентября, 2018 - 03:14:54
Post Id



Администратор
Эксперт


Просматривает форум
Сообщений всего: 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.

Второй вызов используется если надо узнать позицию только одного выбранного фрагмента:

CODE:
regexstart(2);

Параметр - число означающее позицию какого фрагмента надо узнать.
В данном примере узнаем стартовую позицию 3 элемента.
Возвращает позицию элемента или -1, если данного элемента нет.


CODE:
regexend(2);

Параметр - число означающее позицию какого фрагмента надо узнать.
В данном примере узнаем финишную позицию 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);
 
 Top
Skycrew
Отправлено: 26 Сентября, 2018 - 04:58:19
Post Id



Пользователь
Мастер


Покинул форум
Сообщений всего: 123
Дата рег-ции: Июль 2014  
Репутация: 0




Вот это офигенно! Я как раз собрался парсер делать) Спасибо!
p.s. К сожалению нет пейпола((
 
 Top
Kibor
Отправлено: 26 Сентября, 2018 - 05:37:32
Post Id



Администратор
Эксперт


Просматривает форум
Сообщений всего: 8217
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 357




Skycrew , Пользуйтесь) Если что не хватает - пишите.
Попозже добавлю еще возврат позиций, работу с char
 
 Top
Kibor
Отправлено: 27 Сентября, 2018 - 08:37:39
Post Id



Администратор
Эксперт


Просматривает форум
Сообщений всего: 8217
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 357




Добавил флаги

IGNORECASE
По умолчанию регулярное выражение чувствительно к регистру. Примените этот режим, чтобы не учитывать регистр. Но наборы символов всегда чувствительны к регистру.

SINGLELINE
По умолчанию точка может соответствовать любому символу, кроме новой строки (\n). Режим SINGLELINE позволит точке соответствовать любому символу.

MULTILINE
Измените "^" и "$" на соответствие началу или концу строки для соответствия началу или концу любой строки в любом месте строки.
SINGLELINE и MULTILINE не исключают друг друга. Они имеют разные функции в разных местах, поэтому их можно использовать вместе.
Утверждения '\A' и '\Z' используются для соответствия только началу и концу строки, независимо от того, указан ли флаг MULTILINE.

GLOBAL
GLOBAL действует только на \G. Он позволяет \G соответствовать окончанию последнего совпадения, когда много раз повторяется. Без флага GLOBAL \G не используется в шаблоне.
По умолчанию операция замены заменит все совпадения, если даже GLOBAL не указан. Если вы не хотите заменять все совпадения, вы можете указать, сколько раз.

RIGHTTOLEFT
Поиск и замена справа на лево.

EXTENDED
Игнорирует символы пробела в шаблоне и рассматривает символы от # до конца строки как примечание.
 
 Top
Kibor
Отправлено: 07 Октября, 2018 - 12:27:13
Post Id



Администратор
Эксперт


Просматривает форум
Сообщений всего: 8217
Дата рег-ции: Март 2013  
Откуда: Одесса
Репутация: 357




Добавил функции возвращающие позиции найденных фрагментов
regexstart - Узнает стартовую позицию найденного фрагмента. Работает только с regexsearch. Использовать данную функцию можно только после вызова regexsearch

regexend - Узнает финишную позицию найденного фрагмента. Работает только с regexsearch. Использовать данную функцию можно только после вызова regexsearch

Подробнее Регулярные выражения
 
 Top
AdryV
Отправлено: 21 Октября, 2018 - 08:18:54
Post Id



Пользователь
Специалист


Покинул форум
Сообщений всего: 449
Дата рег-ции: Май 2016  
Репутация: 11




подскажите возможно ли с помощью этой функции выполнить это
152211(50),5663(60)
нужно что бы записало число 152211 в один массив а что в скобках 50 в другой массив
под тем же номером ну и так несколько раз
(Добавление)
я так понимаю ток такой способ?
CODE:
string P[50];
string T="152211(50),5663(60)";
string R="\d+";
int te[50];
int te1[50];

int k=regexsearch(-1, #P[0], T, R);
messagebox (k);
for (int n=0; n<k; n++)
{
te[n]=formatsn(P[n]);
messagebox (te[n]);
n++;
te1[n]=formatsn(P[n]);
messagebox (te1[n]);
}
 
 Top
Zireael
Отправлено: 21 Октября, 2018 - 11:31:18
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 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]);
}

Если в строке могут быть пробелы, то это тоже надо учесть в регулярном выражении.
 
 Top
Zireael
Отправлено: 02 Декабря, 2018 - 14:06:28
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 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];
 
 Top
Dantes3000
Отправлено: 03 Февраля, 2019 - 22:35:17
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 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+ (Отобразить)
 
 Top
Zireael
Отправлено: 03 Февраля, 2019 - 23:14:22
Post Id



Пользователь
Эксперт


Покинул форум
Сообщений всего: 4461
Дата рег-ции: Нояб. 2017  
Репутация: 585




CODE:
string text="a (1).jpg # 15:30 4.2.19 # "+"Строчка 1 ^n Строчка 2. #";

string array[3]; // сюда результат запишется
string r="[^^#]+"; // регулярное выражение
messagebox(r);

int x=regexsearch(sizearray(array), #array[0], text, r);
messagebox("Найдено совпадений: "+format(x));
for(int i=0; i<x; i++)messagebox(array[i]);
 
 Top
Страниц (25): [1] 2 3 4 5 6 7 8 9 » В конец
Сейчас эту тему просматривают: 4 (гостей: 4, зарегистрированных: 0)
« О программе Кибор »


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




Powered by