URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10297
[ Назад ]

Исходное сообщение
"Возможно ли на regexp perl удалить определенное число байтов?"

Отправлено zhukovia , 05-Фев-20 13:29 
Есть строка текста в которой в произвольном месте может содержаться "мусорный" текст который нужно вычистить. У "мусора" следующие параметры он оканчивается на \x00\x00 (в hex представлении), а в начале \xE3\x33 но при этом он не всегда находится в самом начале иногда перед ним бывает 1 или 2 символа. При этом длинна "мусорной" строки всегда 70 байт. Встречается "мусор" произвольное число раз.

Возможно ли на Perl составить такое регулярное выражение или два три выражения которое удаляло бы ненужное?



Содержание

Сообщения в этом обсуждении
"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено zhukovia , 05-Фев-20 13:41 
Забыл добавить подобная последовательность (\x00\x00) может быть не один раз внутри "мусора". И начинается не строго с \xE3\x33. В начале бывает еще 1-2 символа произвольных, но длинна всегда 70 байт.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 05-Фев-20 14:10 
> Забыл добавить подобная последовательность (\x00\x00) может быть не один раз внутри "мусора".
> И начинается не строго с \xE3\x33. В начале бывает еще 1-2
> символа произвольных, но длинна всегда 70 байт.

На перле это делается как два пальца об асфальт, остается только понять что такое "бывает 1-2 символа" и как эти два символа отличить от остальной части строки.
Регексы требуют четкости, а не размытых формулировок.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено zhukovia , 06-Фев-20 07:23 
>> Забыл добавить подобная последовательность (\x00\x00) может быть не один раз внутри "мусора".
>> И начинается не строго с \xE3\x33. В начале бывает еще 1-2
>> символа произвольных, но длинна всегда 70 байт.
> На перле это делается как два пальца об асфальт, остается только понять
> что такое "бывает 1-2 символа" и как эти два символа отличить
> от остальной части строки.
> Регексы требуют четкости, а не размытых формулировок.

Согласен что нужно четко описывать, но проблема в том что эти 1-2 символа никак не отличить от нормальной строки поэтому я пошел другим путем. Сначала перевернул строку, а потом искал \x00\x00 и от них уже искал 70 байт и вырезал, потом строку обратно переворачивал.
$row = reverse($row);
$row=~s/\x00\x00.{68}//g;
$row = reverse($row);
Возможно перевороты туда сюда и не оптимальны но это работает.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 06-Фев-20 12:27 
> Согласен что нужно четко описывать, но проблема в том что эти 1-2
> символа никак не отличить от нормальной строки поэтому я пошел другим
> путем. Сначала перевернул строку, а потом искал \x00\x00 и от них
> уже искал 70 байт и вырезал, потом строку обратно переворачивал.
> $row = reverse($row);
> $row=~s/\x00\x00.{68}//g;
> $row = reverse($row);
> Возможно перевороты туда сюда и не оптимальны но это работает.

Это сферическое "черезжопу" в вакууме.
Внизу есть решение нарезки по 70.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Аноним , 06-Фев-20 00:14 
> Есть строка текста в которой в произвольном месте может содержаться "мусорный" текст
> который нужно вычистить. У "мусора" следующие параметры он оканчивается на \x00\x00
> (в hex представлении), а в начале \xE3\x33 но при этом он
> не всегда находится в самом начале иногда перед ним бывает 1
> или 2 символа. При этом длинна "мусорной" строки всегда 70 байт.
> Встречается "мусор" произвольное число раз.
> Возможно ли на Perl составить такое регулярное выражение или два три выражения
> которое удаляло бы ненужное?

Что-то такое, если я вас верно понял.

$clean = do{ use bytes ; $str =~ s/.{68}\x00{2}(?!=\x00)//g ; $str }


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено ACCA , 06-Фев-20 01:11 
>> Е> Что-то такое, если я вас верно понял.
> $clean = do{ use bytes ; $str =~ s/.{68}\x00{2}(?!=\x00)//g ; $str }

Так оно не проверит на \xE3\x33. Нужно тщательнее:

$clean = do{ use bytes;
  $str =~ s/\xE3\x33.{66}\x00{2}//og;
  $str =~ s/.\xE3\x33.{65}\x00{2}//og;
  $str =~ s/..\xE3\x33.{64}\x00{2}//og;
  $str }


Три простых регекса отработают в разы быстрее одного сложного.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Аноним , 06-Фев-20 03:31 
> Так оно не проверит на \xE3\x33. Нужно тщательнее:

Если в данных не бывает \0\0, удаляемый кусок всегда 70 байт и оканчивается двумя и более \0, моего решения достаточно.
Без конкретики в условиях лучше не переусложнять.

> Три простых регекса отработают в разы быстрее одного сложного.

Это не сложное выражение.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 06-Фев-20 12:20 
> Это не сложное выражение.

(?!=\x00) - что это значит?
Есть:
(?=ххх) заглядывание вперед
(?!xxx) заглядывание вперед с отрицанием
а что у вас нифига не понятно, думаю что скорее второе.

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


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Аноним , 07-Фев-20 00:47 
>> Это не сложное выражение.
> (?!=\x00) - что это значит?
> Есть:
> (?=ххх) заглядывание вперед
> (?!xxx) заглядывание вперед с отрицанием
> а что у вас нифига не понятно, думаю что скорее второе.
> Вообще в силу формулировки афтара, его следовало бы послать ... формулировать, а
> не гадать не пойми на чем.

Думал сначала написать ?=[^\x00], а потом исправил и знак равно забыл убрать. Регулярку конечно не тестил.
Посылать неправильно. Вопрос корректный. Возможно? Возможно. Он же не попросил сразу годного в продакшен решения.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 07-Фев-20 14:02 
> Думал сначала написать ?=[^\x00], а потом исправил и знак равно забыл убрать.
> Регулярку конечно не тестил.
> Посылать неправильно. Вопрос корректный. Возможно? Возможно. Он же не попросил сразу годного
> в продакшен решения.

Дак афтур и толком задачу не сформулировал - в оригинальной формулировке ее вообще решить невозможно.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Аноним , 07-Фев-20 14:37 
Примерно же понятно. Есть какой-то бинарный протокол, по которому чанки данных идут с каким-то заголовком. Так-то конечно надо изучать протокол и делать unpack по формату.
Но регулярки fine too, это же перл.

"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено zhukovia , 06-Фев-20 07:29 
> $clean = do{ use bytes ; $str =~ s/.{68}\x00{2}(?!=\x00)//g ; $str }

(?!=\x00) как я понимаю эта конструкция будет искать \x00{2} после которых нет \x00, а в строке может быть и несколько кусков такого мусора. Так что не сработает. Я поступил в "лоб" развернул строку и искал уже с конца \x00{2} и потом резал 70 байт.



"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 06-Фев-20 12:26 
> (?!=\x00) как я понимаю эта конструкция будет искать \x00{2} после которых нет
> \x00, а в строке может быть и несколько кусков такого мусора.

видимо тут (?!\x00), и видимо оно будет учитывать что в мусоре \x00 не только в конце две штуки, ибо исходя из твоей формулировки мусор кончается двумя \x00, про наличие внутри ни сказано ниху ... ничего.
> Так что не сработает. Я поступил в "лоб" развернул строку и
> искал уже с конца \x00{2} и потом резал 70 байт.

Это какой-то бред.

Может сначала попытаться немного изучить perl regex? А не брать хау-ту рецепты без понимания?


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Аноним , 07-Фев-20 00:50 
>> $clean = do{ use bytes ; $str =~ s/.{68}\x00{2}(?!=\x00)//g ; $str }
> (?!=\x00) как я понимаю эта конструкция будет искать \x00{2} после которых нет
> \x00, а в строке может быть и несколько кусков такого мусора.
> Так что не сработает. Я поступил в "лоб" развернул строку и
> искал уже с конца \x00{2} и потом резал 70 байт.

Да, ?!= - опечатка, должно быть ?!

Конструкция смотрит 2 нулевых байта, после которых нет нулевых байтов, после чего удаляет их вместе с 68 байтами стоящими перед ними.
Если \0\0 в длину удаляемой строки не входят, нужно вместо {68} написать {70}.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено Pahanivo , 07-Фев-20 14:01 
> Конструкция смотрит 2 нулевых байта, после которых нет нулевых байтов, после чего
> удаляет их вместе с 68 байтами стоящими перед ними.
> Если \0\0 в длину удаляемой строки не входят, нужно вместо {68} написать
> {70}.

Значит я правильно понял.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено U.N.Owen , 08-Фев-20 14:05 
> Есть строка текста в которой в произвольном месте может содержаться "мусорный" текст
> он оканчивается на \x00\x00
> (в hex представлении), а в начале \xE3\x33 но при этом он
> не всегда находится в самом начале иногда перед ним бывает 1
> или 2 символа. При этом длинна "мусорной" строки всегда 70 байт.

Этому определению строки строго соответствует регексп

(?=.{0,2}\xE3\x33).{68}\x00{2}
Дальше понятно, или нужно разжевывать?

"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено ACCA , 10-Фев-20 21:06 
>> (в hex представлении), а в начале \xE3\x33 но при этом он
>> не всегда находится в самом начале иногда перед ним бывает 1
>> или 2 символа. При этом длинна "мусорной" строки всегда 70 байт.
> Этому определению строки строго соответствует регексп
(?=.{0,2}\xE3\x33).{68}\x00{2}

> Дальше понятно, или нужно разжевывать?

Ага. Разжуй две ситуации, в которых твой regex не сработал:
   1. Перед \xE3\x33 есть ОДИН символ
   2. Перед \xE3\x33 есть ДВА символа. Строка осталась 70 байтов. А ты ожидаешь 72.


"Возможно ли на regexp perl удалить определенное число байтов?"
Отправлено U.N.Owen , 28-Мрт-20 19:45 
> Ага. Разжуй две ситуации, в которых твой regex не сработал:
>    1. Перед \xE3\x33 есть ОДИН символ

И?
{0, 2}, если что, включает в себя 1.

>    2. Перед \xE3\x33 есть ДВА символа. Строка осталась 70
> байтов. А ты ожидаешь 72.

Регексп работает и ожидает 70 символов. (?=.....) — это просмотр вперёд, если что. Далее отсчет идет с начала строки.