Что нового

Помогите распарсить текстовый файл

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Имеется текстовый файл такой структуры:
Код:
[некий текст 1]
Другой текст 1
[некий_текст_2]
Другой_текст_2
[некий текст 3]
Другой 
текст3
[некий текст 4]
Другой

текст4
Задача собрать данные из него в двухмерный массив типа:
Dim $aAllText[2][$n]
$aAllText[0][$n] = "[некий текст 1]" ;без скобок
$aAllText[1][$n] = "Другой текст 1" ; включая символы переноса строки если они есть
Тоесть текст в квадратных скобках связан с текстом, который идёт после него с новой строки и вплоть до следующего фрагмента в квадратных скобках.
Мой подход был такой:
Код:
#Include <Array.au3>

$sAllText = @ScriptDir & "\Gen_Common.lin.bf.txt"
$hOLIfile = FileOpen ($sAllText, 0+128) ;открываем файл в режиме чтения
$iStr = 1 ; номер элемента
Dim $aAllText[101][2]; объявляем массив
While 1
	If $iStr > 100 Then ExitLoop
	$sOLIfile = FileReadLine ($hOLIfile)
	If StringLeft ($sOLIfile, 1) = "[" And StringRight ($sOLIfile, 1) = "]" Then ; если по краям есть скобки
		$aAllText[$iStr][0] = StringTrimRight (StringTrimLeft ($sOLIfile, 1), 1) ; записываем эту строку в массив, отрезая скобки
		$aAllText[$iStr][1] = FileReadLine ($hOLIfile); следующая строка по любому без скобок b относится к предыдущему тексту
		$iStr += 1
	EndIf
WEnd
FileClose ($hOLIfile)
_ArrayDisplay($aAllText)

Но он не годится, так как в тексте бывает по несколько строк и все они должны быть в одной ячейке массива, а FileReadLine это всё срезает

Подскажите более правильную реализацию.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ynbIpb

Код:
#Include <Array.au3>
$sAllText = @ScriptDir & "\Gen_Common.lin.bf.txt"
$hOLIfile = FileOpen ($sAllText, 0)
$text = FileRead($hOLIfile)
FileClose ($hOLIfile)
$a=StringRegExp($text, '(?s)(\[.*?\])(?:\r\n)([^\[]*)', 3)
$n=UBound($a)
Dim $aAllText[Int($n/2)][2]
For $i = 0 to $n-1 Step 2
	$aAllText[$i/2][0]=$a[$i]
	$aAllText[$i/2][1]=$a[$i+1]
Next
_ArrayDisplay($aAllText)


Регулярное выражение подразумевает отсутствие [ в тексте, если оно должно быть, кроме как в начале и в конце, то нужно немного переделать.
 

axlwor

Скриптер
Сообщения
657
Репутация
147
Код:
#include <array.au3>
$sText = '[некий текст 1]' & @CRLF
$sText &= 'Другой текст 1' & @CRLF
$sText &= '[некий_текст_2]' & @CRLF
$sText &= 'Другой_текст_2' & @CRLF
$sText &= '[некий текст 3]' & @CRLF
$sText &= 'Другой' & @CRLF
$sText &= 'текст3' & @CRLF
$sText &= '[некий текст 4]' & @CRLF
$sText &= 'Другой' & @CRLF
$sText &= '' & @CRLF
$sText &= 'текст4' & @CRLF
$aA = StringSplit($sText, '[]')
_ArrayDisplay($aA)
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
axlwor
Так тоже можно

Код:
#Include <Array.au3>
$sAllText = @ScriptDir & "\Gen_Common.lin.bf.txt"
$hOLIfile = FileOpen ($sAllText, 0)
$text = FileRead($hOLIfile)
FileClose ($hOLIfile)
$a = StringSplit($text, '][', 2)
$n=UBound($a)
Dim $aAllText[Int($n/2)][2]
For $i = 1 to $n-2 Step 2
	$aAllText[($i-1)/2][0]='['&$a[$i]&']'
	$aAllText[($i-1)/2][1]=StringTrimLeft($a[$i+1], 2)
Next
_ArrayDisplay($aAllText)


но нельзя чтоб "[" и "]" были по тексту


Окончательно:
Код:
#Include <Array.au3>
$sAllText = @ScriptDir & "\Gen_Common.lin.bf.txt"
$hOLIfile = FileOpen ($sAllText, 0)
$text = FileRead($hOLIfile)
FileClose ($hOLIfile)
$a=StringRegExp($text&'[', '(?s)(\[.*?\])(?:\r\n)(.*?)(?=\r\n\[)', 3)
$n=UBound($a)
Dim $aAllText[2][Int($n/2)]
For $i = 0 to $n-1 Step 2
	$aAllText[0][$i/2]=$a[$i]
	$aAllText[1][$i/2]=$a[$i+1]
Next
_ArrayDisplay($aAllText)
 

axlwor

Скриптер
Сообщения
657
Репутация
147
Автор. А зачем делать массив? Чем одномерный не радует?

Код:
[0]|[некий текст 1]|Другой текст 1
[1]|[некий_текст_2]|Другой_текст_2
[2]|[некий текст 3]|Другойтекст3
[3]|[некий текст 4]|Другойтекст4
 
Автор
ynbIpb

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Большое спасибо за решения!
axlwor [?]
А зачем делать массив?
Ну мне кажется это удобным, что каждый фрагмент в своей ячейке и не нужно лепить дополнительных разделителей. И есть вероятность, что символ | встретится в тексте и будет косяк.
 

axlwor

Скриптер
Сообщения
657
Репутация
147
неее. это так копирует _arraydisplay. я имею ввиду зачем делать массив

0 1
0 Значение00 Значение01
1 Значение10 Значение11
2 Значение20 Значение21
....
n Значениеn0 Значениеn1

ps. вопрос информационный, для собственного любопытства
 
Автор
ynbIpb

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Это текст из игры FromDust, которую переводят на русский язык.
там игровой архив, внутри архива много много файлов, в которых хранится сам текст. Бывает одно слово, а бывает пара абзацев.
Я написал экстрактор текста в один файл в удобоваримом виде, где [текст в скобках] означает имя файла, из которого извлекли текст, а всё что после этой строки сам текст.
Вот когда переведут его, необходимо всё запихать обратно. Вот работая с массивом мне будет удобнее это сделать.
 
Верх