Что нового

Не хочет обрабатыватся строчка

assch

Новичок
Сообщения
166
Репутация
4
Если обработать этим скриптом файл Test.txt то на выходе мы увидим что строчки
"RegexIndentBegin"="^.*\\{[^}\\\"']*$"
"RegexIndentEnd"="^(.*\\*/)?\\s*\\}[;\\s]*$"
"RegexIndentStatement"="^.*;[\\s]*$"
Просто проигнорированны и не попадают в выстроенную строчку
Не кто не знает почему?
[Ключ]
"RegVersion"=dword:0
"Cust"=hex:f3,\
00,cc,00,\
00,00
"IgnoreIndent"="^\\s*(#.*|.*:smile:\\s*$"
"RegexIndentBegin"="^.*\\{[^}\\\"']*$"
"RegexIndentEnd"="^(.*\\*/)?\\s*\\}[;\\s]*$"
"RegexIndentStatement"="^.*;[\\s]*$"
"RegexIndentBegin"="aaa"
"RegexIndentEnd"="bbb"
"RegexIndentStatement"="ccc"
"Clr3"=hex:fe,ff,\
ff,00,\
00,fd,\
00,00
"Tmpl"=""
Код:
#include <File.au3>
Global $Array
Global $Mas
_FileReadToArray("Test.txt",$Mas)
For $i = 1 To $Mas[0]
$result = StringInStr($Mas[$i],"[")
if $result = 1 Then
$Array &= $Mas[$i]    
EndIf
if $result NOT = 1 and  $Mas[$i] = True Then
$Array &= "|||" & $Mas[$i] 
EndIf
if $Mas[$i] = "" Then
$Array &= @CR    
EndIf
Next
$Txt = FileOpen("Ключ.txt" ,2)
FileWrite($Txt, $Array)
FileClose($Txt)
 

asdf8

Скриптер
Сообщения
564
Репутация
152
А так ?

Код:
#include <File.au3>
Global $Array
Global $Mas
_FileReadToArray("Test.txt", $Mas)
For $i = 1 To $Mas[0]
	Select
		Case StringInStr($Mas[$i], "[")
			$Array &= $Mas[$i]
		Case $Mas[$i] = ""
			$Array &= @CR
		Case Else
			$Array &= "|||" & $Mas[$i]
	EndSelect
Next
$Txt = FileOpen("Ключ.txt", 2)
FileWrite($Txt, $Array)
FileClose($Txt)
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Это уже лучше.
Только он после этих строчек не ставит разделитель "|||"
Мне этот раделитель нужен потом для обратной динамики.
Может ещё что то нужно добавить ?
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
"IgnoreIndent"="^\\s*(#.*|.*:smile:\\s*$"
"RegexIndentBegin"="^.*\\{[^}\\\"']*$"
"RegexIndentEnd"="^(.*\\*/)?\\s*\\}[;\\s]*$"

Мне нужно что бы он после каждой строчки ставил "|||"
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Код:
$str = FileRead("Test.txt")
$aSection = StringRegExp($str, '(?s)(?:^|[\r\n])(\[.+?(?=$|\n\[))', 3)
$sOut = ''
If IsArray($aSection) Then
	For $i=0 To UBound($aSection)-1
		$aSection[$i]=StringRegExpReplace($aSection[$i], '(?s)(.+?)[\r\n]*$', '\1')
		$aSection[$i]=StringReplace($aSection[$i], @CRLF, "|||")
		If $aSection[$i] Then
			$sOut &= $aSection[$i] & @CRLF
		EndIf
	Next
	If $sOut Then
		$file = FileOpen("Ключ.txt", 2)
		FileWrite($file, $sOut)
		FileClose($file)
	EndIf
EndIf
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Спасибо asdf8
Пока вроде работает
Не подскажешь в чём именно была проблема?
 

asdf8

Скриптер
Сообщения
564
Репутация
152
[?]
Цитата сказал(а):
чём именно была проблема?

Под условие :
Код:
StringInStr($Mas[$i],"[")

попадают строчки:
Код:
"RegexIndentBegin"="^.*\\{[^}\\\"']*$"
"RegexIndentEnd"="^(.*\\*/)?\\s*\\}[;\\s]*$"
"RegexIndentStatement"="^.*;[\\s]*$"

т.е. ошибка в алгоритме обработки
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
А к чему лишние телодвижения ?
Разве нельзя так :
Код:
$sStr = FileRead("Test.txt")
$sOut=StringRegExpReplace($sStr,"(.+?)\r\n","\1|||")& @CRLF
If @extended <> 0 Then
	$hFile = FileOpen("Ключ.txt", 2)
	FileWrite($hFile, $sOut)
	FileClose($hFile)
EndIf


Если чтение идет из ini-файла то и для него можно составить рег. выражение
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Спасибо gregaz
За интересное и красивое решение.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
assch [?]
но можно чтобы оставался между ключами один пробел.

Я попробовал твой скрипт и получил с 1-м пробелом.
Тестировал на файле "Ключ.txt" в который несколько раз заносил строки своим вариантом при $hFile = FileOpen("Ключ.txt", 1).

Проверь свой файл : "Ключ.txt" . Там строки должны быть без пустых строк(которые ты называешь пробелами).
Если у тебя в нем текст идет через строчку - убери в моем варианте или у тебя где-то лишнее @CRLF
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Спасибо gregaz
Я закоментировал часть кода для обратной динамики и всё стало нормально
Код:
#include <File.au3>

$sFile1 = "1.txt"
$sFile2 = "1.reg"

Reg_out($sFile1,$sFile2)

Func Reg_out($sFile_in,$sFile_out)
Local $Mas
Local $Array
_FileReadToArray($sFile_in, $Mas)
If @error Then Return SetError(4, 4, "")
;$Array &= "Windows Registry Editor Version 5.00" & @CRLF 
$Array &= "REGEDIT4" & @CRLF
For $i = 1 To $Mas[0]
;if StringInStr($Mas[$i],"[") = 1 Then
;$Array &= @CR
;EndIf
$Split = StringSplit($Mas[$i], "|||",1)
For $p = 1 To $Split[0]
$Array &= $Split[$p] & @CR
Next
Next
$Txt = FileOpen($sFile_out,2)
FileWrite($Txt, $Array)
FileClose($Txt)
EndFunc



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

Честно говоря пока не понимаю вот этого:
"(.+?)\r\n","\1|||"
Что означают эти символы
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
assch [?]
Что означают эти символы

\r\n - это тот же @CRLF (перевод каретки)
"(.+?) - все ,что до перевода каретки (?- Предпочтительный выбор наименьшего фрагмента перед большим )
\1- это так называемая обратная ссылка -эквивалент содержимого скобки (.+?)

Выражение предлагает заменить в тексте каждый фрагмент до перевода строки на этот же фрагмент , но с добавлением |||
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Большое спасибо gregaz за информацию.
Всем спасибо.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Кстати это же можно получить и без рег.выражения :
Код:
$sOut=StringReplace($sStr,@CRLF,"|||")& @CRLF
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4


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

Я понял
довольно оригинально
Только мне нужно чтобы каждый ключ с его значениями был на отдельной строчке
Алгоритм такой:
Ключи какой нибудь ветки реестра выстраиваются построчно
После модификации этой ветки опять тоже самое
Потом сравнение этих снимков
После сравнения остаются строчки только добавленных ключей
Ну и обратной динамикой выстраивается reg файл дабавленных ключей
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Если я правильно понял задачу ,то проще сделать так :

Код:
#include<Array.au3>
#include<File.au3>
;Получение исходного текста Так :
	$sText = FileRead("Test.txt")
;Или (если необходим массив) так :
	Dim $aStr
	_FileReadToArray("Test.txt",$aStr)
	_ArrayDisplay($aStr,'$aStr')
	$sText=_ArrayToString($aStr, @CRLF, 1)
	MsgBox(0,'$sText',$sText)
;Получение строки ключей с их значениями :
	$sOut=StringRegExpReplace($sText,"\r\n[^\r\n\[]","|||")
	MsgBox(0,'$sOut',$sOut)
;-Повторение,сравнивание и т.п.
	;................................
;Получение массива - результата :
	$aRez=StringRegExp($sOut,"(.*?)(?:\|\|\||\r\n|[^|]$)",3)
	_ArrayDisplay($aRez)
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Спасибо Форумчанам за советы .С вашей помощью получился первый прикид.
На основе тестов более быстрыми получились эти скрипты.
Первый скрипт для снятия снимка ветки реестра с последующим выстраиванием значений ключей в строчку:
Код:
_RegString('HKEY_USERS', 'HKU.txt')

Func _RegString($sKey,$sFile)
Local $Path,$PID,$sPath = 'regedit.exe'
Local $tPath = DllStructCreate('wchar[1024]')
Local $Ret = DllCall('shlwapi.dll', 'int', 'PathSearchAndQualifyW', 'wstr', StringStripWS($sPath, 7), 'ptr', DllStructGetPtr($tPath), 'int', 1024)
If @error Then
Return SetError(1, 0,$sPath)
EndIf
$Path= DllStructGetData($tPath, 1)
$PID = Run($Path & ' /e /s "' & $sFile & '" "' & $sKey & '"')
If @error Then
Return 0
EndIf
ProcessWaitClose($PID)
$sStr = FileRead($sFile)
$sOut=StringRegExpReplace($sStr,"(.+?)\r\n","\1|||")
If @extended <> 0 Then
$hFile = FileOpen($sFile, 2)
FileWrite($hFile, $sOut)
FileClose($hFile)
EndIf
EndFunc

Второй скрипт для обратной динамики:
Код:
#include<File.au3>

$sFile1 = "HKU.txt"
$sFile2 = "HKU.reg"

_RegOut($sFile1,$sFile2)

Func _RegOut($sFile_in,$sFile_out)
Local $Mas
Local $Array
_FileReadToArray($sFile_in, $Mas)
If @error Then Return SetError(4, 4, "")
$Array &= "REGEDIT4" & @CR & @CR
For $i = 1 To $Mas[0]
$Split = StringSplit($Mas[$i], "|||",1)
For $p = 1 To $Split[0]
$Array &= $Split[$p] & @CR
Next
Next
$Txt = FileOpen($sFile_out,2)
FileWrite($Txt, $Array)
FileClose($Txt)
EndFunc

Если кто то предложит более быстрый способ, буду признателен.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
assch [?]
Если кто то предложит более быстрый способ, буду признателен.

А почему бы не прочитать файл "HKU.txt" не в массив , а в текст :
Код:
$sText = FileRead($sFile1)


И затем через регулярное выражение получить массив фрагментов ,находящихся перед "|||"
и записать его в файл "HKU.reg" через ф-ию _FileWriteFromArray.

По- моему это проще



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

Или произвести замену "|||" на @CRLF сразу во всем тексте : $sText и записать его в файл : "HKU.reg" ,
что еще проще и быстрее ,т.к. обходимся без массива.
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Честно говоря не допонял
Измени мой скрипт чтобы наглядно было видно
 
Верх