Что нового

выборка из текстового файла фрагментов, помеченных тегами

man_without_face

Новичок
Сообщения
17
Репутация
0
Всем здравствуйте!
Начал осваивать нашу замечательную программу только недавно. Делаю на работе один проект по автоматизированной обработке анкет. На данный момент столкнулся с такой вот задачей.
Имеются анкеты, в которых формируется машиносчитываемый блок. Анкеты распознаются сканированием и результат помещается в текстовый файл. Текст содержит много лишней информации, т.к. при поточном сканировании в зону распознавания могут попасть лишние данные. Нужные блоки выделены тегами "<" и ">" - в них содержатся данные с разделителем в виде ";". В тексте таких блоков много - по количеству анкет. За раз от 10 до 50, может и больше.
Считывать файл с такими данными (где каждая строка с разделителями относится к одной записи, количество строк не ограничено) и вносить их в программу уже могу. Но теперь нужно создать такой файл из получаемого при распознавании текста.
Таким образом есть текст " какой-то текст <фамилия;имя;...> ещё текст <фамилия;имя;...> ещё текст..."
Надо получить
"Фамилия;имя
Фамилия;имя
...
"
Либо сразу помещать в двухмерный массив. Количество столбцов всегда 25, строк - по количеству анкет.
Буду благодарен за любую помощь.
 
A

Alofa

Гость
man_without_face сказал(а):
... Но теперь нужно создать такой файл из получаемого при распознавании текста...
Насколько я вас понял:
Код:
$sFile = @ScriptDir & '\TextFile.txt' ; TXT файл
$sTextFile = FileRead($sFile) ; Считываем весь текст с распознанного TXT файла
$sOutput = StringRegExpReplace($sTextFile, '.*?<([^;]+?);([^;]+?);[^<]*', '$1 $2' & @CRLf) ; Выбрасываем мусор
If @error = 2 Then MsgBox(16, 'ОЙ', 'ОШИБОЧКА!')

$hFile = FileOpen($sFile, 2)
If $hFile = -1 Then Exit MsgBox(16, "Ошибка", "Невозможно открыть файл для перезаписи.")
FileWrite($hFile, $sOutput) ; Перезаписываем исходный TXT файл
FileClose($hFile)
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
Спасибо! Почти так. На выходе в строке должны быть разделители, но это я поправил. И в строке я указал только фамилию и имя для краткости, на самом деле там 25 позиций. Но это тоже поправимо. А вот что осталось, так это:
1. Не убрался лишний текст от начала до первого открывающего тега.
2. На выходе изначальный текст, если имеются пустые записи ( в тексте они в виде двух разделителей вподряд - к примеру, если не указано отчество, то "фамилия;имя;;01.01.1999;...и т.д.")
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
man_without_face
помещать в двухмерный массив
Код:
$s = " какой-то текст < фамилия;имя; ; 01.01.1999;.;.;.;;;;1;2;3;4;5;6;7;8;9;0;;;;;25> ещё текст <фамилия ; имя;;01.01.1999 ;.;.;.;;;;1;2;3;4;5;6;7;8;9;0;;;;;25> ещё текст...<26 колонок;   фамилия;   имя;;01.01.1999;.;.;.;;;;1;2;3;  4;5;6;7;8;9;0;;;;;25><фамилия;имя;;01.01.1999;.;.;.;;;;1;2;3;4;5;6;7;8;9;0;;;;;25>"
$c = 0
$a1 = StringRegExp($s, "\<(.*?)\>", 3)
Dim $a2[UBound($a1)][25]
For $i = 0 To UBound($a1) - 1
  $ar = StringSplit($a1[$i], ";", 2)
  If UBound($ar) <> 25 Then
    MsgBox(0, "Error", $a1[$i])
    ContinueLoop
  EndIf
  For $j = 0 To 24
    $a2[$c][$j] = StringStripWS($ar[$j], 3)
  Next
  $c += 1
Next
ReDim $a2[$c][25]

#include <Array.au3>
_ArrayDisplay($a2)
 
A

Alofa

Гость
man_without_face сказал(а):
... но это я поправил.
Интересно как?

Попробуйте так:
(сейчас проверить нет возможности)
Код:
; ...
$sOutput = StringRegExpReplace($sTextFile, '.*?<(.*?)>[^<]*', '$1' & @CRLf)
; ...
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
InnI, изящно! Работает прям так, как хотелось.
Правда всплыла одна проблема.
Оказывается иногда при сканировании могут не распознаваться разделители, в этом случае программа дает ошибку. Поработаю, конечно, над качеством распознавания, но хотелось бы на этот случай предусмотреть проверку правильности. Я так понимаю, надо проверять, на сколько разделяется $a1 и если меньше 25 или больше, то данную запись пропускать, можно выдать окошко с текстом, что запись $a1 не обработана. Такую анкету на повторную обработку.

И надо убирать пробелы перед и после ";" - при распознавании иногда вставляются. Но это, думаю не сложно.


Alofa, Ваш вариант тоже рассматриваю и проверю попозже.
Разделители добавил вставив их между $1 $2 $3...
Т.е. стало '$1;$2;$3...'
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
man_without_face
Добавил проверку и удаление пробелов (см. ответ #3).
 
A

Alofa

Гость
man_without_face сказал(а):
... Оказывается иногда при сканировании могут не распознаваться разделители...
Тогда даже и не заморачивайтесь с моим скриптом.
Есть идея получше, но это вечером.

Еще хотел спросить: вам в итоге нужен почищенный файл или массив для дальнейшей работы?
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
Alofa сказал(а):
Идею жду, спасибо.

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

Alofa

Гость
man_without_face имеются вопросы:
[list type=decimal][*]Текст между тегами "<>" всегда кириллица?
[*]Текст между тегами "<>" - первый блок всегда начинается с заглавной буквы?
[*]Текст между тегами "<>" - последний блок тоже заканчивается знаком ";" ?
[*]Текст перед "<" всегда один и тот же?
[*]Текст после ">" всегда один и тот же?[/list]
К чему эти вопросы? Нужно узнать: при отсутствии одного из знаков "<" или ">"от чего отталкиваться.
Было бы проще если вы скинули пример такого файла.
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
Текст между тегами "<>" всегда кириллица?
- да, всегда.

Текст между тегами "<>" - первый блок всегда начинается с заглавной буквы?
- первой идет фамилия. По-идее, с большой буквы, но как распознает finereader - гарантировать нельзя.

Текст между тегами "<>" - последний блок тоже заканчивается знаком ";" ?
-нет, последняя запись заканчивается тегом >.

Текст перед "<" всегда один и тот же?
Текст после ">" всегда один и тот же?
- нет, случайный набор букв или символов - что отсканируется или распознаётся вокруг блока с данными.
К сожалению, заметил, что может получиться и знак > или <. Знал бы, делал бы теги сложнее, но программа, формирующая этот блок уже разослана исполнителям. Конечно, можно учесть в будущем и внести изменения, но пока так. Там еще формируется pdf417 штрих-код, с ним надежнее, но с ним пока другие проблемы, поэтому пока не использую.

К чему эти вопросы? Нужно узнать: при отсутствии одного из знаков "<" или ">"от чего отталкиваться.
Было бы проще если вы скинули пример такого файла.
-при нарушении корректности блока проще его игнорировать (с уведомлением) и обрабатывать анкету заново, либо вводить вручную. Хотя, это не наш метод )) все автоматизировать!

Попробую завтра на работе сделать тестовый файл.

Что ещё из особенностей. В блоках некоторых записи из нескольких слов, с пробелами. Есть блоки с цифрами, датами, комбинацией цифр и букв, цифры, разделенные знаком "-". Другие символы вроде не тспользуются.
 
A

Alofa

Гость
На данном этапе могу предложить только это:
Код:
$sFileIN = @ScriptDir & '\TextFile.txt' ; TXT файл
$sFileOUT = @ScriptDir & '\TextFile[NEW].txt' ; TXT файл с результатом

$sTextFile = StringRegExpReplace(FileRead($sFileIN), '[<>]', @CRLF) ; Считываем весь текст из TXT файла и заменяем в нем все знаки "<" и ">" на символ переноса строки
$sTextFile = StringRegExpReplace($sTextFile, '(?m)^([^;]*)\R', '') ; Удаляем строки не содержащие знак ";"
If @error = 1 Then MsgBox(16, 'ОЙ', 'ОШИБОЧКА!')

$hFile = FileOpen($sFileOUT, 2)
If $hFile = -1 Then Exit MsgBox(16, 'Ошибка!', 'Не удалось создать файл "TextFile[NEW].txt".')
FileWrite($sFileOUT, $sTextFile) ; Записываем все в новый файл
FileClose($hFile)

; Просмотр результата для проверки
ShellExecute($sFileIN)
ShellExecute($sFileOUT)
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
А как быть, если среди "мусора" тоже окажется знак ";"?
Что если при ошибке распознавания внутри тегов окажется разрыв строки?

По второму вопросу - надо сначала удалить все имеющиеся разрывы строк, а потом уже менять < и >, я так понимаю.


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

InnI сказал(а):
man_without_face
Добавил проверку и удаление пробелов (см. ответ #3).

Скрипт работает отлично. Вставил в свою программу, тестирую в основном на обработку данных в некорректном виде. Пока один вероятный косяк нашел - если в мусоре будет случайный знак открывающего тега и до следующего открывающего тега не будет разрыва строки, то данные от него помещаются в первый блок. Т.е. "аракадабра<Фамилия". Конечно не факт, что такое будет, но все же. Более сложный тег решил бы проблему, но пока как есть.


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

Вот примерный исходный текст. Добавил в него косяков
 

Вложения

  • образец.txt
    2.9 КБ · Просмотры: 4
A

Alofa

Гость
man_without_face сказал(а):
... Вот примерный исходный текст. Добавил в него косяков
Вот так бы сразу :smile:

И сразу вопрос:
- та "машинка" которая распознает текст, если не понимает "<" или ">", какой-то знак все равно выставляет?
- такие 2 блока: "... ,11-12;01.04.16>" всегда присутствуют и идут последними ( т.е. 24 и 25) в каждой анкете?


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

man_without_face сказал(а):
... Более сложный тег решил бы проблему
Не факт. Избавление от процедуры распазнования решило бы проблему.
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
"Машинка" - обычная связка планшетного сканера документов и программы FineReader. По началу был косяк со знаком "<" - распознавал как "С", но помогло обучение.

Что касается блоков 24 и 25, чаще всего будут пустые.


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

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

Вложения

  • barcodes.txt
    1.3 КБ · Просмотры: 4
A

Alofa

Гость
Вариант 1:
man_without_face сказал(а):
По началу был косяк со знаком "<" - распознавал как "С", но помогло обучение.
Что касается блоков 24 и 25, чаще всего будут пустые.

То есть, теперь мы знаем что каждая анкета железно начинается на "<", далее идут 25 блоков разделенных ";" . 25й блок либо пустой, либо имеет формат "01.04.16" и оканчивается либо на ">", либо пробелом?

Вариан 2:
man_without_face сказал(а):
... В общем, это отдельная история, но зато исключается некорректное распознавание блоков.

Так может стоит уже двигаться в этом направлении?
Насколько я понял, сейчас у вас схема такая:
- Документ --> сканер --> FineReader --> текст.файл.txt. И все это в потоке.
А что если предложить:
- Документ --> сканер --> картинка --> pdf417--> текст.файл.txt. Что касается последних 2х пунктов, то сделать все в потоке вам поможет Autoit.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
man_without_face
если в мусоре будет случайный знак открывающего тега
Можно либо изменить регулярное выражение (нашёл в инете - поиск самого глубокого блока)
Код:
$a1 = StringRegExp($s, "(?=[^\<]*\>)(.*?)\>", 3)
Либо такую строку тоже считать ошибкой
Код:
If UBound($ar) <> 25 Or StringInStr($a1[$i], "<") Then
 
Автор
M

man_without_face

Новичок
Сообщения
17
Репутация
0
Alofa сказал(а):
Вариант 2:
документ --> сканер --> картинка --> pdf417--> текст.файл.txt. Что касается последних 2х пунктов, то сделать все в потоке вам поможет Autoit.[/spoiler]

Затык был в том, что программа, распознающая pdf417, если сканировать прямо в ней, уж очень долго инициализирует сканер и не позволяет за раз отсканировать больше одного листа. Думаю пойти другим путём - другой программой или через драйвер сканера отсканировать сначала все анкеты в папку, а затем уже с помощью autoit обработать их программой-распознавалкой.
В наличии имеется программа, в которой можно отсканировать много листов и сохранить, автоматически присваивая имена по типу: имя01.jpg ... имя99.jpg

Autoit умеет составлять список файлов в папке? Или подсчитывать их количество?
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
OffTopic:
man_without_face
Autoit умеет составлять список файлов в папке? Или подсчитывать их количество?
Конечно, умеет. Поиск заработает - найдёте.
 
A

Alofa

Гость
man_without_face что скажете по Варианту 1?
OffTopic:
Дайте ссылку на программу, которой пользуетесь для распознавания pdf417
 
Верх