Что нового

Обработка текста (удаление строк по условиям)

KarSar

Новичок
Сообщения
15
Репутация
0
Версия AutoIt: v3.3.7

Описание:

Выбрать *.txt файл. Обработать следующим образом:
Найти и удалить строки в которых НЕТ слово "печать". Т.е. оставить только те строки в которых есть слово "печать".
Затем с помощью регулярного выражения удалить все, кроме первых 5 символов строки и до слово "печать".
Затем удалить все TAB после слово "печать".
Эти данные необходимо сохранить в файл с именем "1.txt"


Примечания:

Строки данных для примера -

Код:
VG587 status time 11:38:30 tren "<Техническая поддержка>" @LAS "Строка с требованием на..." (<ПЕЧАТЬ>)SLKFHY897E 	-LKJS09F	-FKLEJNER(<'end'>)
VV951 status time 22:18:30 tren "<Техническая поддержка>" @LAS "Строка с требованием на..." (<ПЕЧАТЬ>)FE89FIJ39F	-FNM92OI	-EFWEFFYT(<'end'>)
VE283 status time 11:24:30 tren "<Техническая поддержка>" @LAS "Просрочено" (<>)F02RJH928F	-M98J908	-H565U690(<'over'>)
VT425 status time 16:33:30 tren "<Техническая поддержка>" @LAS "Строка с требованием на..." (<ПЕЧАТЬ>)9JHH4928UI	-NMOWEHF	-K645YH56(<'end'>)
VH245 status time 14:37:30 tren "<Техническая поддержка>" @LAS "Просрочено" (<>)LU983OR098	-KJH9JKH	-56J56J56(<'over'>)
VS093 status time 11:18:30 tren "<Техническая поддержка>" @LAS "Строка с требованием на..." (<ПЕЧАТЬ>)FJ89O3IJ4T	-NLKWENL	-UKYUKYUK(<'end'>)
VJ432 status time 21:32:30 tren "<Техническая поддержка>" @LAS "Просрочено" (<>)8N9843F938	-FLWENFL	-GKUKYUKG(<'over'>)

Спасибо!
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
какого вида должна быть строка?
 

erlik

Продвинутый
Сообщения
317
Репутация
84
Если не сильно заморачиваться, то примерно так:
Код:
#include <File.au3>

Local $sFile,$hFile,$sLine,$sNewText=''
$sFile='test.txt'
$hFile=FileOpen($sFile)

While 1
    $sLine = FileReadLine($hFile)
    If @error = -1 Then ExitLoop
    If StringRegExp($sLine,'.*(печать|ПЕЧАТЬ).*') Then
		$sNewText&=$sLine & @CRLF
		;ConsoleWrite($sLine & @CRLF)
    EndIf
WEnd
FileClose($hFile)
$hFile=FileOpen($sFile,2)
FileWrite($hFile,$sNewText)
FileClose($hFile)

------------------------------------------------------
Упс...Пункты 2 и 3 недочитал. :smile: ладно, может попозже доделаю. Если никто не выложит примера.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
KarSar,
Можно примерно так сделать.
Код:
Local $s_FileRead = @ScriptDir & '\txt.txt', $a_Read, $s_Txt, $i_Tmp, $s_FileWrite, $i_Count, $i_FormatCount, $h_File

$s_Txt = FileRead($s_FileRead)
;~ $a_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(\(<(?:печать|ПЕЧАТЬ).+?)(?=[\n\r]|$)', 3)
;вернет строки вида: VG587 (<ПЕЧАТЬ>)SLKFHY897E -LKJS09F -FKLEJNER(<'end'>)
$a_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(?<=печать|ПЕЧАТЬ)>\)(.+?)\(<', 3)
;вернет строки вида: VG587 SLKFHY897E -LKJS09F -FKLEJNER
$i_Tmp = UBound($a_Read)
If (Not $i_Tmp) Or (Mod($i_Tmp, 2)) Then Exit 13
$i_FormatCount = StringLen($i_Tmp / 2)
$s_Txt = 'Строки, содержащие печать или ПЕЧАТЬ, кол-во ' & $i_Tmp / 2 & @CRLF & 'Из файла ' & $s_FileRead & @CRLF & @CRLF
For $i = 0 To $i_Tmp - 1 Step 2
	$i_Count += 1
	$s_Txt &= StringFormat('%' & $i_FormatCount & 's\t%s %s\r\n', $i_Count, $a_Read[$i], StringStripWS(StringReplace($a_Read[$i + 1], @TAB, ''), 4))
;~ 	$s_Txt &= $a_Read[$i] & ' ' & StringStripWS(StringReplace($a_Read[$i + 1], @TAB, ''), 4) & @CRLF
Next
$s_Txt = StringTrimRight($s_Txt, 2)
;~ ConsoleWrite($s_Txt & @LF)
$i_Tmp = StringInStr($s_FileRead, '\', 0, -1)
$s_FileWrite = StringLeft($s_FileRead, $i_Tmp) & 'Print_' & StringTrimLeft($s_FileRead, $i_Tmp)
$h_File = FileOpen($s_FileWrite, 2)
FileWrite($h_File, $s_Txt)
FileClose($h_File)
Очень не хватает кнопки с autoit-тегами.
KarSar [?]
Выбрать *.txt файл. Обработать следующим образом:
ИМХО, было бы удобнее указать папку с этими файлами и обработать их все.
 
Автор
K

KarSar

Новичок
Сообщения
15
Репутация
0
joiner сказал(а):
какого вида должна быть строка?

Строка вида:
VG587(<ПЕЧАТЬ>)SLKFHY897E-LKJS09F-FKLEJNER(<'end'>)
Хотя это для примера, Я то потом и что то другое могу добавить

P.S. Спасибо! Даже как то обрадовался ) Сегодня вечером сяду посмотреть код. Но если кто то еще добавит, будет здорово!!! :laugh:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
KarSar [?]
Строка вида:
VG587(<ПЕЧАТЬ>)SLKFHY897E-LKJS09F-FKLEJNER(<'end'>)
Не понятно, зачем нужен (<'end'>)?
Мой, исправленный, вариант с (<'end'>).
Код:
Local $s_FileRead = @ScriptDir & '\txt.txt', $a_Read, $s_Txt, $i_Tmp, $s_FileWrite, $h_File

$s_Txt = FileRead($s_FileRead);читаем обрабатываемый файл
$a_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(\(<(?:печать|ПЕЧАТЬ).+?)(?=[\n\r]|$)', 3)
;~ 1	(?<=[\n\r]|^)				- проверка совпадения слева символов переноса строки "[\n\r]" или "|" начала текста "^"
;~ 2	(.{5})						- забираем пять любых символов, если совпадают все условия
;~ 3	[^\n\r]+					- проверяем наличие любых символов, кроме символов переноса строки "[^\n\r]" в количестве больше одного "+"
;~ 4	(\(<(?:печать|ПЕЧАТЬ).+?)	- забираем текст, начинающийся с (< "\(<", проверяя наличие в нем печать или "|" ПЕЧАТЬ "(?:печать|ПЕЧАТЬ)" и все
;~ 									  следующие символы в количестве больше одного ".+?" до совпадения с условием на следующей строке
;~ 5	(?=[\n\r]|$)				- проверка совпадения справа символов переноса строки "[\n\r]" или "|" конца текста "$"
;~ В итоге получаем массив, в котором в индексах 0, 2, 4 и т.д. находятся символы из условия 2, например "VG587", "VV951" и т.д., а в индексах 1, 3, 5 и т.д.
;~ находятся символы из условия 4, например "(<ПЕЧАТЬ>)SLKFHY897E 	-LKJS09F	-FKLEJNER(<'end'>)", "(<ПЕЧАТЬ>)FE89FIJ39F	-FNM92OI	-EFWEFFYT(<'end'>)" и т.д.
$i_Tmp = UBound($a_Read); получаем размер массива
If (Not $i_Tmp) Or (Mod($i_Tmp, 2)) Then Exit 13;если размер 0 или не кратен 2, выход, так как это ошибка
$s_Txt = 'Файл ' & $s_FileRead & @CRLF & @CRLF; задаем новый текст
For $i = 0 To $i_Tmp - 1 Step 2; в цикле с шагом два от 0 до последнего индекса массива
    $s_Txt &= $a_Read[$i] & StringStripWS($a_Read[$i + 1], 8) & @CRLF
;~ добавляем к тексту символы из условия 2 " $s_Txt &= $a_Read[$i]",
;~ символы из условия 4, предварительно удалив из них все пробельные символы " & StringStripWS($a_Read[$i + 1], 8)",
;~ символы переноса строки " & @CRLF"
Next
$s_Txt = StringTrimRight($s_Txt, 2);удаляем два последних символа переноса строки "@CRLF"
$i_Tmp = StringInStr($s_FileRead, '\', 0, -1);получаем номер вхождения последнего обратного слеша в пути к обрабатываемому файлу
$s_FileWrite = StringLeft($s_FileRead, $i_Tmp) & 'Print_' & StringTrimLeft($s_FileRead, $i_Tmp)
;~ задаем имя файла-результата, добавляя к имени обрабатываемого файла 'Print_'
$h_File = FileOpen($s_FileWrite, 2);открываем файл-результат и получаем его дескриптор
FileWrite($h_File, $s_Txt);пишем в него новый текст
FileClose($h_File);закрывем дескриптор файла-результата
Без (<'end'>).
Код:
Local $s_FileRead = @ScriptDir & '\txt.txt', $v_Read, $s_Txt, $i_Tmp

$s_Txt = FileRead($s_FileRead)
$v_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(\(<(?:печать|ПЕЧАТЬ).+?)\(', 3)
$i_Tmp = UBound($v_Read)
If (Not $i_Tmp) Or (Mod($i_Tmp, 2)) Then Exit 13
$s_Txt = 'Файл ' & $s_FileRead & @CRLF & @CRLF
For $i = 0 To $i_Tmp - 1 Step 2
	$s_Txt &= $v_Read[$i] & StringStripWS($v_Read[$i + 1], 8) & @CRLF
Next
$s_Txt = StringTrimRight($s_Txt, 2)
$i_Tmp = StringInStr($s_FileRead, '\', 0, -1)
$v_Read = FileOpen(StringLeft($s_FileRead, $i_Tmp) & 'Print_' & StringTrimLeft($s_FileRead, $i_Tmp), 2)
FileWrite($v_Read, $s_Txt)
FileClose($v_Read)
 
Автор
K

KarSar

Новичок
Сообщения
15
Репутация
0
madmasles сказал(а):
KarSar [?]
Строка вида:
VG587(<ПЕЧАТЬ>)SLKFHY897E-LKJS09F-FKLEJNER(<'end'>)
Не понятно, зачем нужен (<'end'>)?
Мой, исправленный, вариант с (<'end'>).
Код:
Local $s_FileRead = @ScriptDir & '\txt.txt', $a_Read, $s_Txt, $i_Tmp, $s_FileWrite, $h_File

$s_Txt = FileRead($s_FileRead)
$a_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(\(<(?:печать|ПЕЧАТЬ).+?)(?=[\n\r]|$)', 3)
$i_Tmp = UBound($a_Read)
If (Not $i_Tmp) Or (Mod($i_Tmp, 2)) Then Exit 13
$s_Txt = 'Файл ' & $s_FileRead & @CRLF & @CRLF
For $i = 0 To $i_Tmp - 1 Step 2
	$s_Txt &= $a_Read[$i] & StringStripWS($a_Read[$i + 1], 8) & @CRLF
Next
$s_Txt = StringTrimRight($s_Txt, 2)
$i_Tmp = StringInStr($s_FileRead, '\', 0, -1)
$s_FileWrite = StringLeft($s_FileRead, $i_Tmp) & 'Print_' & StringTrimLeft($s_FileRead, $i_Tmp)
$h_File = FileOpen($s_FileWrite, 2)
FileWrite($h_File, $s_Txt)
FileClose($h_File)
Без (<'end'>).
Код:
Local $s_FileRead = @ScriptDir & '\txt.txt', $v_Read, $s_Txt, $i_Tmp

$s_Txt = FileRead($s_FileRead)
$v_Read = StringRegExp($s_Txt, '(?<=[\n\r]|^)(.{5})[^\n\r]+(\(<(?:печать|ПЕЧАТЬ).+?)\(', 3)
$i_Tmp = UBound($v_Read)
If (Not $i_Tmp) Or (Mod($i_Tmp, 2)) Then Exit 13
$s_Txt = 'Файл ' & $s_FileRead & @CRLF & @CRLF
For $i = 0 To $i_Tmp - 1 Step 2
	$s_Txt &= $v_Read[$i] & StringStripWS($v_Read[$i + 1], 8) & @CRLF
Next
$s_Txt = StringTrimRight($s_Txt, 2)
$i_Tmp = StringInStr($s_FileRead, '\', 0, -1)
$v_Read = FileOpen(StringLeft($s_FileRead, $i_Tmp) & 'Print_' & StringTrimLeft($s_FileRead, $i_Tmp), 2)
FileWrite($v_Read, $s_Txt)
FileClose($v_Read)

Уважаемый madmasles Спасибо Вам огромное! А не могли бы прокомментировать построчно какая строка что выполняет. Или если есть справка более подробная. Я написал свой вариант, который по сути мне будет удобнее использовать

Код:
$s_FileRead = FileOpenDialog("Открыть...", @DesktopDir, "Text Files (*.txt)", 1 ) ; выбрать файл
If @error Then Exit


;~ Поиск нужных строк и форматирование с помощью регулярных выражений
;~ копирования результата в буфер обмена для вставки в новый файл и сохранения нового файла без изименения открытого


SAVE()

Func SAVE()

;~ $save = FileSaveDialog ( "Сохранить", @DesktopDir, "Txt files (*.txt)",2) ; Самомоу выбрать название
;~ If @error Then Exit

$save = @ScriptDir & '\Выгрузка' & ' (' & @MDAY & '.' & @MON & '  ' & ' ' & @HOUR & '_' & @MIN & '_' & @SEC & ' )' ; Сюда ввести название файла
$File = FileOpen($save & ".txt",2)
$bufer = ClipGet() ; Вставить из буфера обмена
FileWrite($File, $bufer)
FileClose($File)
EndFunc

Буду очень признателен за помощь!
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
KarSar,
Я добавил комментарии в вариант с (<'end'>), времени на это у меня ушло больше, чем на сам код. :smile:
И еще:

Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


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

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
KarSar
Код:
Global $str = FileRead('text.txt')
$str = StringRegExpReplace($str, '((([\r\n]*\w{5})(.*)((\(<ПЕЧАТЬ>\))(\S+)\s+(\S+)\t(.*)))|([\r\n]*.*))', '\3\6\7\8\9')
FileWrite('1.txt', $str)

Оптимизировать не хотел, извини :smile:
 
Автор
K

KarSar

Новичок
Сообщения
15
Репутация
0
Спасибо за помощь!

P.S. простите за нарушения :smile:
 
Верх