Форум: "Прочее";
Текущий архив: 2014.01.19;
Скачать: [xml.tar.bz2];
Внизнечеткий custom датасет Найти похожие ветки
← →
Обычный Порошок (2013-08-02 12:11) [40]Автор, выкуси регулярками число и дату.
После выкусывания останется только второе поле.
Это же так просто.
← →
брат Птибурдукова (2013-08-02 12:20) [41]Я так понимаю, автора интересует не частный случай "число, строка, дата", а более общее решение.
← →
Обычный порошок (2013-08-02 12:24) [42]Тогда тем более регулярки
← →
Плохиш © (2013-08-02 13:42) [43]
> Это же так просто.
А поговорить?
А чсд поднять?
← →
разработчик (2013-08-02 14:38) [44]уж не с тобой ли предлагаешь поговорить
← →
Юрий Зотов © (2013-08-02 15:14) [45]Даже и регулярки не нужны, и парсеры тоже. Простыми строковыми функциями обойтись можно.
1. Выкусываем число (от начала строки до первого пробела).
2. Выкусываем дату (от последнего пробела до конца строки).
3. Остался текст с разделяющими пробелами. Делаем ему trim - и все ОК.
← →
Юртй Зотов (2013-08-02 15:17) [46]Добавление к [45].
Соответственно, если StrToInt (в п.1) или StrToDate (в п.2) дает исключение, то это нарушение формата, исключение вполне честное.
← →
Юрий Зотов © (2013-08-02 15:24) [47]Хех... в собственном нике опечатался... и ведь не пил ничего, кроме кофе. Причем даже и без коньяка (увы!).
:o)
← →
Юрий Зотов © (2013-08-02 15:34) [48]А еще точнее так:
Если StrToInt (в п.1) дает исключение, или если пробелов нет, то число и дата отсутствуют.
Если StrToDate (в п.2) дает исключение, или если второго пробела нет, то дата отсутствует.
Если после trim остается пустая строка, то текст отсутствует.
← →
Юрий Зотов © (2013-08-02 17:56) [49]Короче, Влад - че-то мне интересно стало. Лови. Распознает любые нужные тебе столбцы, причем в любом их количествеих.
============= DFM ===============
object Form1: TForm1
Left = 240
Top = 117
BorderStyle = bsDialog
Caption = "Form1"
ClientHeight = 301
ClientWidth = 688
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = "MS Sans Serif"
Font.Style = []
OldCreateOrder = False
Position = poDesktopCenter
OnCreate = FormCreate
PixelsPerInch = 120
TextHeight = 16
object Panel1: TPanel
Left = 0
Top = 0
Width = 688
Height = 41
Align = alTop
TabOrder = 0
object edSource: TEdit
Left = 316
Top = 8
Width = 121
Height = 24
TabOrder = 0
end
object btnGo: TButton
Left = 516
Top = 12
Width = 75
Height = 25
Caption = "Go!"
Default = True
TabOrder = 1
OnClick = btnGoClick
end
end
object Panel2: TPanel
Left = 0
Top = 41
Width = 688
Height = 41
Align = alTop
TabOrder = 1
object edNumber: TEdit
Left = 92
Top = 12
Width = 121
Height = 24
ReadOnly = True
TabOrder = 0
end
object edText: TEdit
Left = 280
Top = 8
Width = 121
Height = 24
ReadOnly = True
TabOrder = 1
end
object edDate: TEdit
Left = 460
Top = 8
Width = 121
Height = 24
ReadOnly = True
TabOrder = 2
end
end
end
============= UNIT ===============
unit Unit1;
interface
uses
SysUtils, Classes, Controls, Forms, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
edSource: TEdit;
btnGo: TButton;
Panel2: TPanel;
edNumber: TEdit;
edText: TEdit;
edDate: TEdit;
procedure FormCreate(Sender: TObject);
procedure btnGoClick(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Panel1.Height := edSource.Height;
btnGo.Align := alRight;
edSource.Align := alClient;
Panel2.Height := edNumber.Height;
edNumber.Align := alLeft;
edDate.Align := alRight;
edText.Align := alClient;
ClientHeight := Panel1.Height + Panel2.Height
end;
procedure TForm1.btnGoClick(Sender: TObject);
var
Source, S: string;
FirstSpacePos, LastSpacePos, IntDummy: integer;
DateDummy: TDateTime;
begin
edNumber.Clear;
edText.Clear;
edDate.Clear;
Source := Trim(edSource.Text);
if Source = "" then // Нет ни одного столбца
Exit;
// Есть по крайней мере один столбец
FirstSpacePos := Pos(" ", Source);
if (FirstSpacePos = 0) then // Есть всего один столбец
begin
if TryStrToInt(Source, IntDummy) then // Это число
edNumber.Text := Source
else
if TryStrToDate(Source, DateDummy) then // Это дата
edDate.Text := Source
else // Это текст
edText.Text := Source;
Exit
end;
// Есть не один столбец
LastSpacePos := Length(Source);
while (LastSpacePos > FirstSpacePos) and (Source[LastSpacePos] <> " ") do
Dec(LastSpacePos);
if (LastSpacePos = FirstSpacePos) then // Есть два столбца
begin
S := Copy(Source, 1, FirstSpacePos - 1);
if TryStrToInt(S, IntDummy) then // Первый столбец - число, тогда второй - текст или дата
begin
edNumber.Text := S;
S := Copy(Source, LastSpacePos + 1, Length(Source) - LastSpacePos);
if TryStrToDate(S, DateDummy) then // Второй столбец - дата
edDate.Text := S
else // Второй столбец - текст
edText.Text := S;
end
else // Первый столбец - не число, тогда он - текст, а второй столбец должен быть датой
begin
edText.Text := S;
S := Copy(Source, LastSpacePos + 1, Length(Source) - LastSpacePos);
if TryStrToDate(S, DateDummy) then // Второй столбец - дата
edDate.Text := S
else // Второй столбец - не дата
raise EParserError.Create("Если первый столбец - текст, то второй должен быть датой")
end;
Exit
end;
// Есть три столбца - число, текст и дата
S := Copy(Source, 1, FirstSpacePos - 1);
if TryStrToInt(S, IntDummy) then // Первый столбец - число
edNumber.Text := S
else // Первый столбец - не число
raise EParserError.Create("Первый столбец должен быть числом");
S := Copy(Source, LastSpacePos + 1, Length(Source) - LastSpacePos);
if TryStrToDate(S, DateDummy) then // Третий столбец - дата
edDate.Text := S
else // Третий столбец - не дата
raise EParserError.Create("Третий столбец должен быть датой");
edText.Text := Trim(Copy(Source, FirstSpacePos + 1, LastSpacePos - FirstSpacePos - 1));
end;
end.
← →
[ВладОшин] © (2013-08-02 19:59) [50]>> raise EParserError.Create("первый столбец не число ..
Это с чего? :)
ps
Я, конечно, понимаю, что часто на идиота похожу тут, но не до такой же степени..
Еще раз. (Да еще раз, да еще много - много..)
Мы ничего не знаем про то, какие где столбцы.
Первый - может быть любой.
Мы же (люди) читаем текст и понимаем, где столбец, какого он типа, и сколько их.
ps2
считать пробелы - не вариант. В столбце типа текст могут быть пробелы как данные.
01,01,2013 "Предложение с пробелом" 65
01,01,2013 "Предложениебезпробела" 65
01,01,2013 "Предложение с пробелом" 65
тут 3 столбца.
Дата, Строка, Число.
01,01,2013 "Предложение с пробелом" 65 цуцуцуцуцу
01,01,2013 "Предложениебезпробела" 65 цуцуцуцу
01,01,2013 "Предложение с пробелом" 65 цуцуцуцуцу
Тут 4
Дата, Строка, Число, Строка
зы3
Мы вообще,
вообще,
вообще
не можем предполагать сколько столбцов,
чем они разделяются,
в каком порядке идут
Человек же видит это.
Как?!
← →
[ВладОшин] © (2013-08-02 20:23) [51]
> 01,01,2013 "Предложение с пробелом" 65 цуцуцуцуцу
> 01,01,2013 "Предложениебезпробела" 65 цуцуцуцу
> 01,01,2013 "Предложение с пробелом" 65 цуцуцуцуцу
на примере
пробел в строке тут компенсируется множеством пробелов между столбцами
Табуляция еще может дать несколько пробелов(визуально)
Еще, работает индуктивность.
Мы смотрим на то как выглядят предыдущие и следующие строки - и делаем вывод
ps
Я вот что подумал.
если применить "эффект прищура".. Если прищурить глаза, то оно все выглядит нечетко, но зато понятно где данные.
Как бы сказать то :)
типа,
-- размыть - навести резкость --
несколько раз подряд
т.е. как бы все загоняем в матрицу,
буква - черная точка, пробел(таб) - белая
Потом к каждой точке матрицы плюсуем цвет, но так, что рядом с черными точками плюсуется больше. А затем, минусуем. Но тоже так, что рядом с белыми минусуется больше.
т.о.
все маленикие провалы (пробелы внутри строк) "срастаются"
А все выступы (жирным)
01,01,2013 "Предложение с пробелом"
01,01,2013 "Предложениебезпробела"
01,01,2013 "Предложение с пробелом"
- "испаряются"
вооот..
Ладно, удалите, пажалуйста :)
Опять кто-то не поймет, а я объяснять устал :))
← →
Anatoly Podgoretsky © (2013-08-02 20:53) [52]> [ВладОшин] (02.08.2013 19:59:50) [50]
“видит это.” так это же
глаза
← →
Алканавт расправил плечи (2013-08-02 21:08) [53]
> [ВладОшин] © (02.08.13 20:23) [51]
а може — два пробела — конец столбца? и всех делов…
← →
turbouser © (2013-08-02 21:37) [54]
> [ВладОшин] ©
>
> Человек же видит это.
Ты же человек. Вот и спроси себя - как?!?!
зы
Ответ очень долго ищут.
← →
Юрий Зотов © (2013-08-02 22:10) [55]> [ВладОшин] © (02.08.13 19:59) [50]
Я исходил из того, что есть три столбца, следующие в порядке "число, текст, дата" и отделенные друг от друга хотя бы одним пробелом. Любые из этих столбцов в любом количестве могут быть пропущены. Если же столбцов больше трех, то их все равно три: первый - число, последний - дата, а все, что между ними - текст (исключая пробелы - разделители столбцов). Текст может содержать внутренние пробелы, число и дата - не могут.
Таким образом, пробелы нигде не считаются, а вычисляются позиции первого и последнего пробелов, чтобы определить количество столбцов - от него зависит интерпретация входной строки. Дальше так:
1) Нет ни одного столбца (все три пропущены) - выход
2) Есть только один столбец (два пропущены) - он может быть любого типа, причем тип определяется попыткой преобразования в число, а если она не прошла - то в дату. Если же не проходят обе попытки, то это текст.
3). Есть два столбца (один пропущен):
3a) Если первый - число, то второй пытаемся преобразовать в дату. Если прошло, то это дата (а текст пропущен) , если не прошло - это текст (а дата пропущена).
3б) Если первый - не число, то это текст, а второй он обязан быть датой.
4). Есть три и более столбца: первый - число, последний - дата, а все, что между ними - текст.
==============
PS
Если ты хочешь, чтобы программа определяла произвольный тип столбцов, следующих в произвольном порядке, то это ИИ. Потому что неформализуемо. Даже Ёксель такого не делает - при малейшем затруднении считает тип строковым.
← →
Юрий Зотов © (2013-08-02 22:13) [56]Но если исходную строку ты получаешь из БД сцеплением ее полей, то тип каждого столбца можно получить из метаданных.
← →
brother © (2013-08-02 22:21) [57]> Ответ очень долго ищут
алгоритм?
← →
turbouser © (2013-08-02 23:48) [58]
> brother © (02.08.13 22:21) [57]
>
> > Ответ очень долго ищут
>
> алгоритм?
ИИ.
← →
Юрий Зотов © (2013-08-03 09:57) [59]> Человек же видит это
В очевидных случаях - да. В неочевидных - нет.
123 Семен Семенович Горбунков 10-11-12
Сколько здесь полей - 1, 2, 3, 4 или 5 ?
Последнее поле - это дата или текст ?
Если дата, то в каком формате (т.е., где в ней день, а где год) ?
На эти вопросы даже и человек ответить не сможет.
← →
Anatoly Podgoretsky © (2013-08-03 10:33) [60]5 полей + арифметическое вычисление = -13
Глаза не врут
← →
[ВладОшин] © (2013-08-03 10:54) [61]
> Юрий Зотов © (03.08.13 09:57) [59]
> > Человек же видит это
> В очевидных случаях - да. В неочевидных - нет.
Упрощаем.
отбросим неочевидные.
Если человек не понимает, компьютер бессилен. Даже если бы был "сИлен" - кто его проверит :)
> Алканавт расправил плечи (02.08.13 21:08) [53]
> > [ВладОшин] © (02.08.13 20:23) [51]
> а може — два пробела — конец столбца? и всех делов…
Именно так и сделал.
Было б.
Но, бывает, что текст (столбец типа string) содержит 2 пробела.. Разделение в 4 пробела уже компенсирует это для восприятия глаза. Более того, в 1 пробел (разделитель меньше чем в тексте!) на большом наборе строк - тоже дает визуально правильное понимание (индукция)
пример ЮЗ
>> 123 Семен Семенович Горбунков 10-11-12
не ясен.
добьем данными
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
глаз говорит, что тут 5 столбцов
число и 4 раза строка. (5й может быть дата, но хрен ее поймешь, значит строка)
>> Даже Ёксель такого не делает - при малейшем затруднении считает тип строковым
Ну и правильно.
Я хочу просто больше вариантов декодирования добавить.
Но и это не все - ёксель еще неправильно определяет колонки (не всегда правильно)
Т.е. итого получается как excell, да
но можно потратить больше времени на определение колонок и их типа.
← →
Обычный Порошок (2013-08-03 11:09) [62]зная, что должно быть в файле, но не зная порядок столбцов и форматы - это загрузить чуть более сложно, чем в случае, когда знаешь все.
именно совсем чуть-чуть.
но не зная что там вообще внутри файла задача усложняется не так уж и сильно. нужно всего лишь вычислить разделитель полей.
← →
Anatoly Podgoretsky © (2013-08-03 14:36) [63]> Обычный Порошок (03.08.2013 11:09:02) [62]
разделитель полей может
быть одновременно и
разделителем строк
← →
Обычный Порошок (2013-08-03 15:11) [64]да неужели?
если между полями в качестве разделителя стоит разделитель строк, то это значит, что у нас файл в котором в каждой строке одно единственное поле.
← →
[ВладОшин] © (2013-08-05 10:54) [65]>> Обычный Порошок
Согласен.
> нужно всего лишь вычислить разделитель полей
В этом и проблема.
зы
1. Метод размыть-сфокусировать долгий.
2.
Есть еще одна идея.. Пусть есть данные:
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
123 Семен Семенович Горбунков 10-11-12
загоним в матрицу координаты начал "слов"
123 начинается с позиции 0
Семен с позиции 5
и т.п.
Матрица чисел
0 5 N1 ..
0 5 N2 ..
Это координата X
Добьем координатой Y, равной номеру строки
Получим матрицу точек.
(0,0) (5,0) (N1,0)..
(0,1) (5,1) (N2,1)..
Зачача провести вертикальные прямые пересекающие как можно больше точек.
← →
Обычный порошок (2013-08-05 10:59) [66]какая проблема?
делаем несколько предположений о разделителях.
пробуем их по очереди.
выбираем тот, при котором максимальное количество строк имеют одинаковое количество полей.
← →
[ВладОшин] © (2013-08-05 11:13) [67]
> делаем несколько предположений о разделителях.
> пробуем их по очереди.
> выбираем тот, при котором максимальное количество строк
> имеют одинаковое количество полей.
равнозначно, вроде
> Получим матрицу точек.
>
> (0,0) (5,0) (N1,0)..
> (0,1) (5,1) (N2,1)..
>
> Зачача провести вертикальные прямые пересекающие как можно
> больше точек.
← →
[ВладОшин] © (2013-08-05 11:24) [68]
> > Зачача провести вертикальные прямые пересекающие как можно
> > больше точек.
стремясь минимизировать их кол-во
под этим надо подумать что означать должно
потому что
1.а
провести вертикальные прямые пересекающие как можно больше точек. - Все точки можно. Имеем over 9000 прямых. Может быть, что на точку будет своя прямая
1.б
>> стремясь минимизировать их кол-во
= 0 прямых. Меньше нельзя :)
Почему прямые - тут учитывается "индуктивность". Т.е. что было и что будет, т.е. как и человек определяет, что это случайный сдвиг, а так - все должно быть и было до этого ровно.
← →
[ВладОшин] © (2013-08-05 11:40) [69]
> стремясь минимизировать их кол-во
дык просто! - если меньше N % точек на линии - разделитель ложный
← →
[ВладОшин] © (2013-08-05 11:42) [70]блин..
однако, вот такой пример - не обработает
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
хотя человек видит, что тут 3 столбца
← →
[ВладОшин] © (2013-08-05 11:45) [71]хотя..
за счет чего видит? за счет многих пробелов между
в копии данных надо удалить пробелы до не более 1 подряд, и на этих данных чертить линии.
Вот это уже может сработать
← →
Обычный порошок (2013-08-05 12:14) [72]какие вертикальные прямые?
какое зрение?
ты импорт пишешь или систему управления планетой?
← →
turbouser © (2013-08-05 12:44) [73]
> [ВладОшин] © (05.08.13 11:45) [71]
А может это два столбца ? Данные - пробелы например. Или "цуцуцу"
← →
[ВладОшин] © (2013-08-05 13:07) [74]
> turbouser © (05.08.13 12:44) [73]
А может это два столбца ?
не, 3 :)
Как тут 2 можно увидеть?
три. Каждая вторая срока сдвинута на символ.
> Обычный порошок (05.08.13 12:14) [72]
> ты импорт пишешь или систему управления планетой?
я пишу как можно более универсальный класс-распознаватель.
для удовольствия.
Прикладной "надо было вчера" уже давно написал, юзается.
Сделал просто заменяется Tab на 3 пробела, и потом если пробелов более 2 подряд - разделитель. Охватывается 99.90% файлов
Но есть пару файлов (из over 9000) которые битые. Они не понимаются и предварительно требуют правки. Не страшно, но неприятно.
ps
Например, есть в одном из них в середине некая строка ИТОГО
т.е.
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
итого: 45
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
цуцуцу цуцуцуцу укукук
(это какая -то прога формировала, видимо. Какая-то древняя, кодировка еще досовская и + стремится форматировать в файле, что, как видно, не всегда удается)
так вот "итого" - тоже не надо.
В новом классе сделал св-во,
property MinLenStr: Integer read FIgnorMinLenStr write FIgnorMinLenStr; // minimum char in str. If less - string ignore
что бы такие досады игнорить
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2014.01.19;
Скачать: [xml.tar.bz2];
Память: 0.64 MB
Время: 0.005 c