Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
1-1320565646
Remad
2011-11-06 10:47
2014.01.19
GETMEM.INC


15-1375123950
Rouse_
2013-07-29 22:52
2014.01.19
Отдам в хорошие руки


4-1267675438
Алексей4105
2010-03-04 07:03
2014.01.19
Как узнать путь к процессу?


15-1374760428
DevilDevil
2013-07-25 17:53
2014.01.19
Интересная задача. Остаток от деления умножением


15-1375303030
KilkennyCat
2013-08-01 00:37
2014.01.19
Просьба. Сделать хорошо Virtual TreeView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский