Что нового

[Массивы] Выборка значений из лога

zigzagrus79

Новичок
Сообщения
31
Репутация
0
Приветствую уважаемые! Регулярные выражения для меня пока-что не по силам. Есть файл log.txt вида: {"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"} и далее в таком же виде}
где первые две цифры координаты, третье значение ник.
Помогите составить функцию чтения из файла. Нужно считывать пару координат и проверять условие, если условие верно выводить ник.
 

_dron_

Знающий
Сообщения
84
Репутация
8
Как то так :smile:

Код:
#include <StringConstants.au3>
#include <Array.au3>

Global $buff, $aListVal, $iListSize

$buff = FileRead("log.txt")

$aList = _toArray($buff)
$iListSize = @extended

_ArrayDisplay($aList)

Func _toArray($Buffer)
	Local $aArray[1][3], $tmp1, $tmp2, $tmp3
	$Buffer = StringReplace($Buffer," ","")
	$tmp1 = StringSplit($Buffer,",",$STR_CHRSPLIT)
	ReDim $aArray[$tmp1[0]][3]
	For $i = 1 to $tmp1[0]
		$tmp2 = StringSplit($tmp1[$i],":",$STR_NOCOUNT)
		$tmp3 = StringReplace($tmp2[0],'"',"")
		$aArray[$i-1][0] = StringReplace($tmp3,"{","")
		$tmp3 = StringReplace($tmp2[1],'"',"")
		$aArray[$i-1][1] = StringReplace($tmp3,"{","")
		$tmp3 = StringReplace($tmp2[2],'"',"")
		$aArray[$i-1][2] = StringReplace($tmp3,"}","")
	Next
	return SetError(0,$tmp1[0],$aArray)
EndFunc

А твое задание разабраться что здесь происходит и дописать свой функционал ;D
 

ildar

Осваивающий
Сообщения
252
Репутация
29
Можно так:
Код:
#include <Array.au3>
$sText = '{"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"}'
$sPattern = '[-0-9А-Яа-я]+'
$aResult = StringRegExp($sText, $sPattern, 3)
_arraydisplay($aResult)
Что дальше со значениями в массиве делать, сам решай.
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
zigzagrus79
Код:
$sData = '{"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"} и далее в таком же виде}'
$aData = StringRegExp($sData, '\"([-\d]+)\":\{\"([-\d]+)\":\"([^"]+)\"', 4)
For $i = 0 To UBound($aData)-1
	$aCoord = $aData[$i]
	ConsoleWrite('Координаты №' & ($i+1) & ': ')
	ConsoleWrite('x=' & $aCoord[1] & '; ')
	ConsoleWrite('y=' & $aCoord[2] & '; ')
	ConsoleWrite('Ник: ' & $aCoord[3] & @CRLF)
Next
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Код:
#include <Array.au3>

$text = '{"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"}'
;$test = FileRead("log.txt") ; дле чтения из файла поставить эту строку вместо предыдущей

$x = 5661	; координата X
$y = -5820	; координата Y

$pattern = '(?s).*?"'&$x&'":{"'&$y&'":"(.+?)"'
$aRes = StringRegExp($text, $pattern, 3)
_arraydisplay($aRes)
 
Автор
Z

zigzagrus79

Новичок
Сообщения
31
Репутация
0
Вот что у меня получилось, рабочий вариант
Код:
#include <Array.au3>
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>
$main = GUICreate("taskmgr", 110, 186, 462, 673)
$Button_Start = GUICtrlCreateButton("Start", 3, 10, 75, 25)
$x= GUICtrlCreateInput("", 15, 40, 50, 21)
$z= GUICtrlCreateInput("", 15, 70, 50, 21)
$rad1 = GUICtrlCreateInput("", 15, 110, 50, 21)
GUISetState(@SW_SHOW)

While 1
     $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
		 Case $Button_Start
            jet_mining_bot ()
		 EndSwitch
	 WEnd
		 
func 	  jet_mining_bot ()
  
    if GUICtrlRead($rad1)=0 then
		   $rad=1
		else
		   $rad=GUICtrlRead($rad1)
		endif
		$xx=GUICtrlRead($x)
		$zz=-GUICtrlRead($z)
		ConsoleWrite('xx=' & $xx & $zz&$rad& @CRLF&'; ')
$sData = FileRead("y:\LootWL.txt")
$aData = StringRegExp($sData, '\"([-\d]+)\":\{\"([-\d]+)\":\"([^"]+)\"', 4)
$s=0
 Dim $ss[60]
For $ii = 0 To UBound($aData)-1
    $aCoord = $aData[$ii]
	for $i=-$rad to 2*$rad
	   if ($xx+$i)=$aCoord[1] then
	   for $o=-$rad to 2*$rad
		  if ($zz+$o)=$aCoord[2] then
			 ConsoleWrite( "Совпадение " & $aCoord[1] & " " & $aCoord[2]&  "Лутал " & $aCoord[3]& @CRLF)
			$ss[$s]="Совпадение " & $aCoord[1] & " " & $aCoord[2]&  " Лутал " & $aCoord[3]
			$s+=1
			
		 			endif
	   next 
endif	   
	   next 
	Next
	_arraydisplay($ss )
endfunc

Все хорошо было до тех пор, пока не наткнулся на запись вида:
,"6312":{"-4452":"Ник1","-4458":"Ник2"},
То есть координата :6312 общая и вместо ,{"6312 ":{"-4452":"Ник1"},"6312 ":{"-4458":"Ник2"}, получается запись ,"6312":{"-4452":"Ник1","-4458":"Ник2"}, и моя программа выдает только Ник1 игнорируя Ник2
 

madmasles

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


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

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
zigzagrus79
Код:
#include <Array.au3>
Global $aPts[0][3]
$sStr = '{"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"},"6312":{"-4452":"Ник41","-4458":"Ник42","4222":"Ник43"}, "1111":{"234":"Nick222"}}'
$aData = StringRegExp($sStr, '\"([-\d]+)\":\{((\"([-\d]+)\":\"([^"]+)\")(,(?3))*)\}', 4)
For $i = 0 To UBound($aData)-1
    $aCoord = $aData[$i]
    ConsoleWrite('Координаты №' & ($i+1) & ': ')
	$x = $aCoord[1]

	If UBound($aCoord) > 6 Then
		ConsoleWrite(@CRLF)
		$aCoord = StringRegExp($aCoord[2], '\"([-\d]+)\":\"([^"]+)\"', 4)
		For $k = 0 To UBound($aCoord)-1
			$y = $aCoord[$k]
			$y = $y[1]
			$nick = $aCoord[$k]
			$nick = $nick[2]
			$pMax = UBound($aPts)
			ReDim $aPts[UBound($aPts)+1][3]
			$aPts[$pMax][0] = $x
			$aPts[$pMax][1] = $y
			$aPts[$pMax][2] = $nick
			ConsoleWrite(@TAB & 'x=' & $x & '; y=' & $y & '; Ник: ' & $nick & @CRLF)
		Next
	Else
		$y = $aCoord[4]
		$nick = $aCoord[5]
		$pMax = UBound($aPts)
		ReDim $aPts[UBound($aPts)+1][3]
		$aPts[$pMax][0] = $x
		$aPts[$pMax][1] = $y
		$aPts[$pMax][2] = $nick
		ConsoleWrite('x=' & $x & '; ')
		ConsoleWrite('y=' & $y & '; ')
		ConsoleWrite('Ник: ' & $nick & @CRLF)
	EndIf
Next

_ArrayDisplay($aPts)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Код:
#include <Array.au3>

$text = '{"5660":{"-5821":"Ник1"},"5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3"},"6312":{"-4452":"Ник4","-4458":"Ник5"}'
;$test = FileRead("log.txt") ; дле чтения из файла поставить эту строку вместо предыдущей

$x = 6312	; координата X
$y = -4458	; координата Y

$pattern = '(?s).*?"'&$x&'":[^}]+?"'&$y&'":"(.+?)"'
$aRes = StringRegExp($text, $pattern, 3)
_arraydisplay($aRes)

$y = -4452	; координата Y

$pattern = '(?s).*?"'&$x&'":[^}]+?"'&$y&'":"(.+?)"'
$aRes = StringRegExp($text, $pattern, 3)
_arraydisplay($aRes)
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
До кучи и мой вариант.
Код:
#include <Array.au3>

Local $sTxt, $aTxt, $aTmp, $aRes[101][3] = [[0, 100]]

$sTxt = '{"5660":{"-5821":"Ник 1"}, "5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3","-5825":"Ник4"},' & _
		'"6312":{"-4452":"Ник5","-4458" : "Ник6", "-4453":"Ник7" , "-4460":"Ник 8" }}'

$aTxt = StringRegExp($sTxt, '(?:^{|,)\s*(.+?:{.+?})', 3)
If @error Then Exit 13
For $i = 0 To UBound($aTxt) - 1
	$aTmp = StringSplit(StringRegExpReplace($aTxt[$i], '[{}"]', ''), ':,')
	If ($aTmp[0] < 3) Or (Not Mod($aTmp[0], 2)) Then ContinueLoop
	$aRes[0][2] = 1
	$aTmp[1] = StringStripWS($aTmp[1], 3)
	Do
		$aRes[0][0] += 1
		If $aRes[0][0] = $aRes[0][1] Then
			$aRes[0][1] += 100
			ReDim $aRes[$aRes[0][1] + 1][3]
		EndIf
		$aRes[$aRes[0][0]][0] = $aTmp[1]
		For $j = 1 To 2
			$aRes[0][2] += 1
			$aTmp[0] -= 1
			$aRes[$aRes[0][0]][$j] = StringStripWS($aTmp[$aRes[0][2]], 3)
		Next
	Until $aTmp[0] = 1
Next
$aTxt = 0
$aTmp = 0
ReDim $aRes[$aRes[0][0] + 1][3]
For $i = 1 To 2
	$aRes[0][$i] = ''
Next
_ArrayDisplay($aRes)
 
Автор
Z

zigzagrus79

Новичок
Сообщения
31
Репутация
0
Премного благодарен за помощь, буду разбираться :beer: :beer:
 

MockeR

Знающий
Сообщения
101
Репутация
14
И мой вариант:
Код:
#include <Array.au3>

Global $result[0][3]
$sTxt = '{"5660":{"-5821":"Ник 1"}, "5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3","-5825":"Ник4"},' & _
        '"6312":{"-4452":"Ник5","-4458" : "Ник6", "-4453":"Ник7" , "-4460":"Ник 8" }}'

$aTxt = StringRegExp($sTxt, '"(-?\d+)":{([^}]+)}', 4)

for $i = 0 to UBound($aTxt) - 1
	$aMatch = $aTxt[$i]
	$aT = StringRegExp($aMatch[2], '"(-?\d+)"\s*:\s*"(.+?)"', 4)
	for $j = 0 to UBound($aT) - 1
		$aMatch1 = $aT[$j]
		ReDim $result[UBound($result) + 1][3]
		$result[UBound($result) - 1][0] = $aMatch[1]
		$result[UBound($result) - 1][1] = $aMatch1[1]
		$result[UBound($result) - 1][2] = $aMatch1[2]
	Next
Next
_ArrayDisplay($result)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
- OffTopic
- всё IMHO

В AutoIt полный набор функций для обработки строк, используя которые можно получить необходимый результат обработки текста. В принципе можно вообще обойтись и без регулярных выражений. Но мы всё же используем регулярные выражения. И, на мой взгляд, чем лучше регулярное выражение, тем меньше остального кода в решении задачи. Идеальный вариант - это когда есть регулярное выражение и всё.
Потому в этом разделе, как мне кажется, мы стремимся составить скрипты, которые дадут необходимый результат в один проход, путём обработки текста одним регулярным выражением, без циклов, без дополнительных операций.
(ну, я лично составляю регулярные выраженния именно с такой целью)
 

MockeR

Знающий
Сообщения
101
Репутация
14
Вот еще вариант:
Код:
$sTxt = '{"5660":{"-5821":"Ник 1"}, "5661":{"-5820":"Ник2"},"5659":{"-5820":"Ник3","-5825":"Ник4"},"6312":{"-4452":"Ник5","-4458" : "Ник6", "-4453":"Ник7" , "-4460":"Ник 8" }}'
$aTxt = StringRegExp($sTxt, '(?:"(-?\d+)"\s*:\s*{)?"(-?\d+)"\s*:\s*"(.+?)"', 3)
For $i = 0 To UBound($aTxt) - 1 Step 3
	If $aTxt[$i] = "" Then $aTxt[$i] = $aTxt[$i - 3]
	ConsoleWrite("x = " & $aTxt[$i] & ", y = " & $aTxt[$i + 1] & ", Nick = " & $aTxt[$i + 2] & @LF)
Next
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Обрабатывать json регуляркой - тот еще мазохизм.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
:
inververs [?]
тот еще мазохизм.
да, в плане парсинга текста, AutoIt сильно уступает тому же python. BeautifulSoup для html/xml, json и csv для одноименных форматов... и не нужно каждый раз изобретать велосипед.
 
Верх