Что нового

Анализ бинарных данных с помощью рег. выражений

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Друзья, нужна помощь "регулярщиков"... Есть некая последовательность байт (данные битмапа):

0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000000...

или

0x
00000000
00000000
00000000
00000000
00000000
00000000
C4C1C100
D4CECE00
C0B8B800
00000000
...

Нужно с помощью рег. выражений определить содержит ли этот бмтмап полупрозрачные точки или нет. За это отвечает четвертый байт для каждой точки. Т.е., если хотя бы один четвертый байт из всей последовательности не равен нулю, то возвращаем 1, в противном случае - 0. В данном примере полупрозрачности нет, т.к. одни нули...

Добавлено:

Другими словами, нужен шаблон, который из вешеприведенной строки убирает каждые первые 6 символов из 8 возможных. Тогда я могу записать так:

Код:
$sData = '0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000000'
$sPattern = ?

If StringReplace(StringRegExpReplace(StringTrimLeft($sData, 2), $sPattern, ''), '0', '') Then
	ConsoleWrite('1' & @CR)
Else
	ConsoleWrite('0' & @CR)
EndIf
 

SyDr

Сидра
Сообщения
651
Репутация
158
Аналогично. Данные изначально в бинарном виде? Тогда ведь даже не надо переводить в строку.

Возвращаемое значение
@error = 0
0 - битмап не содержит полупрозрачных точек
1 - битмап содержит как минимум одну полупрозрачную точку
@error = 1
0 - входные данные не бинарные
@error = 2
0 - число байтов не кратно 4

Код:
$sData = '0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000000'

MsgBox(4096, Default, F(Binary($sData)))

Func F($bData)
	If Not IsBinary($bData) Then Return SetError(1, 0, 0)
	If Mod(BinaryLen($bData), 4) <> 0 Then Return SetError(2, 0, 0)

	For $iCount = 4 To BinaryLen($bData) Step 4
		If BinaryMid($bData, $iCount, 1) <> 0x00 Then Return 1
	Next

	Return 0
EndFunc
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Спасибо, но я просил с помощью рег. выражений (даже тему так назвал). Проверить в массиве я и сам могу, но скорость... Например битмап 128x128 содержит 16384 точек с соответствующими последствиями... Именно поэтому я и хотел использовать рег. выражения. В принципе я уже и сам составил шаблон. Вроде правильно...

Код:
$sData = '0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000000'

If StringReplace(StringRegExpReplace(StringTrimLeft($sData, 2), '(.{6})(.{2})', '\2'), '0', '') Then
	ConsoleWrite('1' & @CR)
Else
	ConsoleWrite('0' & @CR)
EndIf
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
SyDr сказал(а):
Поменял последний 0 на 1, функция всё равно 0 возвращает.

Код:
;$sData = '0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000000'
$sData = '0x000000000000000000000000000000000000000000000000C4C1C100D4CECE00C0B8B80000000001'

If StringReplace(StringRegExpReplace(StringTrimLeft($sData, 2), '(.{6})(.{2})', '\2'), '0', '') Then
    ConsoleWrite('1' & @CR)
Else
    ConsoleWrite('0' & @CR)
EndIf


Все работает.

:-\
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
StringInStr() не пойдет, т.к. не обязательно должна быть 1, любое число, отличное от 0.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Супер! ~ в 6 раз быстрее моего варианта (хотя время и так незначительное).
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Да, действительно.

:ok:
 
Верх