Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.01.19;
Скачать: CL | DM;

Вниз

нечеткий 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;
Скачать: CL | DM;

Наверх




Память: 0.65 MB
Время: 0.01 c
2-1363671419
Andrey K
2013-03-19 09:36
2014.01.19
Как в Win 8 скопировать отредактированный DELPHI32.DCI


2-1363761523
Андрей2000
2013-03-20 10:38
2014.01.19
Не работает кнопка


15-1375043600
Petr
2013-07-29 00:33
2014.01.19
DB/2. ацтой или рай?


15-1375543089
Anatoly Podgoretsky
2013-08-03 19:18
2014.01.19
Test


15-1375475402
Юрий
2013-08-03 00:30
2014.01.19
С днем рождения ! 3 августа 2013 суббота