Что нового

StringRegExp как найти в промежутке

maxd2007

Новичок
Сообщения
89
Репутация
0
Есть фаил который я открываю бинарно, в нем нужно найти адрес по маске (70|30) b5 [7-22] 01 24 [5-15] ff f7 ?? ?? (01 a8|08 a8|68 46) ff f7 [60-100] 01 24 ?? ?? ?? ?? (30|70) bd - незнаю на каком языке она написана но суть ее такова: первое число 70 или 30 (это начало адреса которое надо получить если вся маска совпадет), константа B5, в промежутке от седьмого байта до 22 искать 0124 (начало промежутка считается от предыдущего значения, в данном случае от B5), в промежутке от пятого байта до 15 искать FFF7 (в данном случае от 0124), любые два байта, одно из трех значений 01a8 или 08a8 или 6846, константа FFF7, в промежутке от 60-го байта до 100-го байта искать 0124(в данном случае ищем от FFF7), пропускаем 4 байта, 30 или 70, константа bd - если все совпадает то функция возвращает адрес (или количество байт от начала фаила до начала маски) начала поиска (в данном случае адрес до (70|30) B5), начал писать:
<autoit>
#include <Array.au3>

$File = FileOpen ( @ScriptDir & "\1.dat", 16 )
if $File = -1 Then
MsgBox (0,"Warning", "File not open")
EndIf
$sText = FileRead ($File)
MsgBox (0,"", $sText)
If StringRegExp($sText, '(70|30)B5') Then
MsgBox(0, 'флаг=0', 'Да, строка содержит маску')
Else
MsgBox(0, 'флаг=0', 'Нет такой строки')
EndIf </autoit>
и понял что не понимаю как мне искать в промежутке (как указано в схеме выше), подскажите пожалуйста как это делать или может я вообще не правильный путь выбрал?
PS
Извиняюсь если неправильно указал тег в котором должен быть заключен скрипт, просто у меня сейчас сайт отображается не так было раньше и нет кнопок для вставки этого кода.
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
Может быть так: Простой пример, есть строка ABBBBBBBBBB, где то после A может находиться цифра 5, но не дальше чем на 4 позиции от A
Значит подойдет такой паттерн: A.{0,4}5
После A, может быть что то, но не больше чем 4 раза, а затем обязательно должна идти 5

Вот возможные правильные:
A5BBBBBBBBBB
AB5BBBBBBBBB
ABB5BBBBBBBB
ABBB5BBBBBBB
ABBBB5BBBBBB
А эта уже не подойдет:
ABBBBB5BBBBB
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
inververs сказал(а):
Может быть так: Простой пример, есть строка ABBBBBBBBBB, где то после A может находиться цифра 5, но не дальше чем на 4 позиции от A
Значит подойдет такой паттерн: A.{0,4}5
После A, может быть что то, но не больше чем 4 раза, а затем обязательно должна идти 5

Вот возможные правильные:
A5BBBBBBBBBB
AB5BBBBBBBBB
ABB5BBBBBBBB
ABBB5BBBBBBB
ABBBB5BBBBBB
А эта уже не подойдет:
ABBBBB5BBBBB
Спасибо, за разжовувающий ответ, вопрос только тогда в знаке ".", если смотреть русскую справку то там сказано "Любой символ кроме переноса......", т.е. то что пишется в фигурных скобках относится к к тому что слева? В данном случае точке.
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
Да, если то что в фигурных скобках работало не к одному символу, а к нескольким - то можно объединить их в группу [что то тут] или в скобки (что то тут)
или если используете скобки, чисто ради группировки, то лучше писать так (?:что то тут)
Например, 2 точки, т.е два символа или байт, можно так записать: A(?:..){0,4}5


Добавлено:
Сообщение автоматически объединено:

Ваш случай: B5(?:..){6}(?:..){0,7}FF
Я ищу байт B5, потом должно идти ровно 6 любых байт (?:..){6}, затем мы можем пропустить до 7 байт (мы можем пропустить 0 байт, или 4), (?:..){0,7} но потом обязательно должна идти FF
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
Огромное спасибо! Еще один небольшой вопрос в догонку: не подскажете как еще мне получить адрес если данная маска верна, есть ли для этого функция или придется ее самому как то писать?
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
Оберните все в ()


Добавлено:
Сообщение автоматически объединено:

Да, еще обратите внимание что пробелы тоже учитываются. Их нужно удалить
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
inververs сказал(а):
Да, если то что в фигурных скобках работало не к одному символу, а к нескольким - то можно объединить их в группу [что то тут] или в скобки (что то тут)
или если используете скобки, чисто ради группировки, то лучше писать так (?:что то тут)
Например, 2 точки, т.е два символа или байт, можно так записать: A(?:..){0,4}5


Добавлено:
Сообщение автоматически объединено:

Ваш случай: B5(?:..){6}(?:..){0,7}FF
Я ищу байт B5, потом должно идти ровно 6 любых байт (?:..){6}, затем мы можем пропустить до 7 байт (мы можем пропустить 0 байт, или 4), (?:..){0,7} но потом обязательно должна идти FF



Попробовал вот так:
<autoit>
$File = FileOpen ( @ScriptDir & "\1.dat", 16 )
if $File = -1 Then
MsgBox (0,"Warning", "File not open")
EndIf
$sText = FileRead ($File)
If StringRegExp($sText, '(70|30)B5.{7-22}0124') Then
MsgBox(0, 'флаг=0', 'Да, строка содержит маску')
Else
MsgBox(0, 'флаг=0', 'Нет такой строки')
EndIf
</autoit>
выдает MSGbox "Нет такой строки", на картинке, что я приложил желтым помечено первое вхождение, а фиолетовым то самое 0124 которое находится в промежутке 7-22 байта от 70B5, я что то неправильно понял?
 

Вложения

  • 53,8 КБ Просмотры: 9

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
Так . это 1 символ. Отсчитайте от B5 22 символа, после них должна быть 01 24, а на картинке 28 14.
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
inververs сказал(а):
Так . это 1 символ. Отсчитайте от B5 22 символа, после них должна быть 01 24, а на картинке 28 14.
Извиняюсь я видать Вас запутал, 0124 должно быть в промежутке 7-22 байта, если брать по символам то это промежуток 14-44, я так понимаю такая маска (?:..) и должна обозначать 1 байт (т.е. 2 символа), попробовал так:
<autoit>StringRegExp($sText, '(70|30)B5(?:..){7}(?:..){0-15}0124') </autoit> т.е. как я понимаю: пропустить 7 байт (т.е. 14 символов) и в диапазоне от 0 до 15 байт (т.е. от 0 до 30 символов) искать 0124, но опять выдает ошибку =(
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
inververs сказал(а):
ну надо {0,15} а у вас минус
После Вашего сообщения вспомнилась фраза: "Шарик ты балбес", совсем запутался уже с символами =), но вот сейчас дошел до момента "или" где 3 значения, и почему то тоже не идет, хотя в самом начале использовал ту же форму
<autoit>StringRegExp($sText, '(70|30)B5(?:..){7}(?:..){0,15}0124(?:..){5}(?:..){0,10}FFF7(?:..){2}(01a8|08a8|6846)') </autoit> т.е. если посмотреть все тот же скрин выше, то видно что после FFF7 через 2 байта идет 08a8 что соответсвует маске, но почему то все равно ошибка =(, попробовал сделать так
<autoit> StringRegExp($sText, '(70|30)B5(?:..){7}(?:..){0,15}0124(?:..){5}(?:..){0,10}FFF7(?:..){2}(01|08|68) (a8|46)') </autoit> до (01|08|68) работает, а если добавляю (a8|46) то не работает =(
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
По картинке трудно ориентироваться. Киньте сюда кусок байтов
(01|08|68) (a8|46) и пробел между частями оставляете?
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
Надеюсь я Вас правильно понял (извиняюсь если нет): 70 B5 05 46 B0 F8 74 01 92 B0 0E 46 00 28 14 BF 01 24 00 24 00 20 8D F8 40 00 68 46 FF F7 26 FE 08 A8 FF F7 23 FE F4 B1 69 46 28 46 FF F7 B6 FF 20 BB 08 A9 28 46 FF F7 1C FE 04 00 1E D1 20 22 68 46 08 A9 5B F2 87 F7 00 28 14 BF 00 20 01 20 07 E0 25 32 58 00 03 00 04 00 90 9F 2D 21 1D 46 19 20 60 B9 0A E0 10 AA 31 46 28 46 FF F7 C6 FD 04 00 04 BF 9D F8 40 00 00 28 00 D0 01 24 12 B0 20 46 70 BD
красным выделил проблемное место, но мне приоритетней будет вариант (01 a8|08 a8|68 46) чем (01|08|68) (a8|46) т.к. 0146 например там быть не должно, его я попробовал чисто для проверки
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
ma:rofl:2007
Пробелы в паттерне учитываются, вам просто программа которой вы смотрите, их добавляет, что бы хоть как то было понятно, в файле же их нет, там все будет так
70B50546B0F8740192B0... смекаете?
Вот вы написали: (01 a8|08 a8|68 46), т.е найти 01 затем пробел затем a8


Добавлено:
Сообщение автоматически объединено:

попробуйте так: (?i)(70|30)B5(?:..){7}(?:..){0,15}0124(?:..){5}(?:..){0,10}FFF7(?:..){2}(01A8|08A8|6846)
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
inververs сказал(а):
ma:rofl:2007
Пробелы в паттерне учитываются, вам просто программа которой вы смотрите, их добавляет, что бы хоть как то было понятно, в файле же их нет, там все будет так
70B50546B0F8740192B0... смекаете?
Вот вы написали: (01 a8|08 a8|68 46), т.е найти 01 затем пробел затем a8


Добавлено:
Сообщение автоматически объединено:

попробуйте так: (?i)(70|30)B5(?:..){7}(?:..){0,15}0124(?:..){5}(?:..){0,10}FFF7(?:..){2}(01A8|08A8|6846)



На счет пробелов Вы правы, но я пробовал без них, проблема оказалась в регистре, я писал маленькие буквы (не обращая на это внимание, а там принципиально нужны были большие =)). Конечный результат таков <autoit>StringRegExp($sText, '(70|30)B5(?:..){7}(?:..){0,15}0124(?:..){5}(?:..){0,10}FFF7(?:..){2}(01A8|08A8|6846)')</autoit> Спасибо Вам еще раз!
 

inververs

AutoIT Гуру
Сообщения
2 135
Репутация
464
А, ну может и регистр не тот, вот эта (?i) в начале позволяет писать в любом регистре )
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
ma:rofl:2007

Предупреждение За нарушение правил форума (пункт В.11):
Любые отрывки AutoIt кода необходимо заключать в тег [autoit]
(подробнее), а обычный код соответственно в тег [code]
(подробнее). Также большие выдержки текста помещайте под тег [spoiler]
(подробнее), там где это поддерживается естественно. Как в случае с названием темы, также короткое и эргономичное сообщение привлекает больше внимания, и шансы на получение конкретного ответа увеличиваются.


С уважением, ваш Глобальный модератор.
 
Верх