Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Алгоритм поиска года в строке!?


Автор: Nicholas 12.9.2009, 14:25
Помогите не могу сообразить как такое сделать. smile

Допустим есть строка  "ывалдо0_2009ывы_ыв22ы" надо написать функцию которая сможет вытащить из строки "2009" и сделает это с любым годом будь это 1900 или 1982 или 2008 smile ну никак не могу придумать.

п.с. Посимвольно в цикле строку прокручивал, проверял явзяется ли символ числом и т.д. и т.п. нифган е получается )))

Автор: Romikgy 12.9.2009, 14:33
regexp те в помощь ,
или просмотр строки посимвольно с поиском 4 цифр подряд (которые начинаются на 19 или 20 )

Автор: Alexeis 12.9.2009, 14:44
 Нижнее подчеркивание всегда присутствует перед годом?

Автор: Nicholas 12.9.2009, 14:53
Цитата(Alexeis @ 12.9.2009,  14:44)
Нижнее подчеркивание всегда присутствует перед годом?

Нет.
Может покажите пример с посимвольным перебором?

Автор: Alexeis 12.9.2009, 15:12
Цитата(Nicholas @  12.9.2009,  13:53 Найти цитируемый пост)
Нет.
Может покажите пример с посимвольным перебором? 

  Функция PosEx , StrUtils. Ищет подстроку в строке. Строку нужно искать '19' и '20' а затем проверять 2 последующих символа.

Автор: Nicholas 12.9.2009, 15:28
Ну не хочется мне искать 19 и 20, хочу чтобы искал любое 4-х значное число в строке, т.к. кроме года в строке других 4-х значных чисел нет.

Вот набросал код  - работает, но получился сильно громоздкий. Облагородьте его пожалуйста! ;)

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function IsDid(ch:string):bool;
begin
  if Pos(ch,'0123456789') <> 0 then
    result:=true
    else
    result:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
st:string;
i,chCount,preChCount:integer;
ch:string[1];
year:string[4];
begin
st:='lkjkljkljlk544_2009fsd54s53f3';
year:='';
chCount:=0;
preChCount:=0;
for I := 1 to length(st) do
begin
  ch:=Copy(st,i,1);
   Memo1.Lines.Add('символ:'+ch);
   
  if IsDid(ch) = true then
  begin
  preChCount:=preChCount+1;
  chCount:=chCount+1;
  Memo1.Lines.Add('символ - число, счетчик сиволов='+IntToStr(chCount));

  if (chCount < 5) and (preChCount>0) then
    begin
    year:=year+ch;
    if chCount = 4 then
      Begin
      Memo1.Lines.Add('Год:'+year);
      End;
    end else
  begin
    chCount:=0;
    year:='';
  end;
  end else
  // if IsDid(ch) = false 
  begin
  preChCount:=preChCount-1;
  chCount:=0;
  year:='';
  if preChCount < 0  then
  preChCount:=0 else
  end;
end;
  

end;

end.


Автор: Alexeis 12.9.2009, 15:44
Цитата(Nicholas @  12.9.2009,  14:28 Найти цитируемый пост)
хочу чтобы искал любое 4-х значное число в строке

  Тогда регуляркой
 [^1234567890] {1}(19|20)[1234567890]{2}[^1234567890] {1}

т.е. перед и после года все что угодно кроме цифр, затем 19 или 20 затем еще 2е любые цифры

Автор: Nicholas 12.9.2009, 16:07
Цитата(Alexeis @ 12.9.2009,  15:44)
  Тогда регуляркой
 [^1234567890] {1}(19|20)[1234567890]{2}[^1234567890] {1}

Первый раз такое вижу! smile Как это выглядит в коде?
 smile 

Автор: Romikgy 12.9.2009, 16:09
\d{4}

Автор: Keeper89 12.9.2009, 16:13
Ну если совсем просто, то можно так:
Код

procedure GetAllUears(const str: String; var yList: TStringList);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 0 to Length(str) - YEAR_LENGTH do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if TryStrToInt(yearStr, myYear) then
      yList.Add(yearStr)
  end;
end;

Автор: Nicholas 12.9.2009, 16:27
Цитата(Keeper89 @ 12.9.2009,  16:13)
Ну если совсем просто, то можно так:
Код

procedure GetAllUears(const str: String; var yList: TStringList);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 0 to Length(str) - YEAR_LENGTH do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if TryStrToInt(yearStr, myYear) then
      yList.Add(yearStr)
  end;
end;

smile)) Ну я тупанул! 

Но,не твой ни мой код вот такую строку st:='lkj20062007kljkljlk544_2009fs2005d54s53f3'; не обрабатывает так,что выводились только года.

Добавлено через 4 минуты и 1 секунду
Вот так вроде работает:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
st:string;
i,chCount,preChCount:integer;
ch:string[1];
year:string[4];
begin
//st:='lkjkljkljlk544_2009fsd54s53f3';
st:='lkj20062007kljkljlk544_2009fs2005d54s53f3';
year:='';
chCount:=0;
preChCount:=0;
for I := 1 to length(st) do
begin
  ch:=Copy(st,i,1);
 //  Memo1.Lines.Add('символ:'+ch);

  if IsDid(ch) = true then
  begin
  preChCount:=preChCount+1;
  chCount:=chCount+1;
//  Memo1.Lines.Add('символ - число, счетчик сиволов='+IntToStr(chCount));

  if (chCount < 5) and (preChCount>0) then
    begin
    year:=year+ch;
    if chCount = 4 then
      Begin
      Memo1.Lines.Add('Год:'+year);
      chCount:=0;
      year:='';
      End;
    end;
  end else
  // если символ не цифра
  begin
  preChCount:=preChCount-1;
  chCount:=0;
  year:='';
  if preChCount < 0  then
  preChCount:=0 else
  end;
end;

Автор: Keeper89 12.9.2009, 16:37
Nicholas, при подобном парсинге надо точнее указывать условия.
Код

procedure GetAllYears(const str: String; var yList: TStringList);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 0 to Length(str) - YEAR_LENGTH do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if (TryStrToInt(yearStr, myYear)) and
       (StrToInt(Copy(yearStr, 1, 2)) in [19, 20]) then
      yList.Add(yearStr)
  end;
end;

Автор: Nicholas 12.9.2009, 16:58
Keeper89, спасибо! Давно не запускал Delphi - все забыл... 

Автор: Keeper89 12.9.2009, 16:59
Nicholas, пожалуйста. И закрывай тему ;)

Автор: Nicholas 12.9.2009, 17:21
Цитата(Keeper89 @ 12.9.2009,  16:59)
И закрывай тему ;)

Закрою, так только ты скажешь как заставить твою процедуру работать с вот этой строкой 'jhhk4cp_tr1_640x000iii2008' smile



Автор: Keeper89 12.9.2009, 18:13
Переделал вот так:
Код

procedure GetAllYears(const str: String; var yList: TStringList);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 0 to Length(str) - YEAR_LENGTH do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if (yearStr[1] in ['1', '2']) and
       (yearStr[2] in ['0', '9']) and
       (yearStr[3] in ['0'..'9']) and
       (yearStr[4] in ['0'..'9']) then
      yList.Add(yearStr)
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  l: TStringList;
begin
  l := TStringList.Create;
  GetAllYears(memo1.Text, l);
  Listbox1.items.assign(l);
end;

Автор: Romikgy 12.9.2009, 18:24
Код

procedure GetAllYears(const str: String;  yList: TStrings);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 1 to Length(str) - YEAR_LENGTH+1 do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if
       (StrToIntDef(Copy(yearStr, 1, 2),0) in [19, 20]) then
      yList.Add(yearStr)
  end;
end;

Автор: Alexeis 12.9.2009, 19:30
Цитата(Nicholas @  12.9.2009,  15:07 Найти цитируемый пост)
Первый раз такое вижу! smile Как это выглядит в коде?


Цитата(Romikgy @  12.9.2009,  13:33 Найти цитируемый пост)
regexp те в помощь ,

Нагугли компонентик такой. Ему присваиваешь регулярку 
'[^1234567890] {1}(19|20)[1234567890]{2}[^1234567890] {1}'
и текст, запускаешь exec и он тебе ищет.

Автор: Nicholas 13.9.2009, 08:16
Цитата(Romikgy @ 12.9.2009,  18:24)
Код

procedure GetAllYears(const str: String;  yList: TStrings);
const
  YEAR_LENGTH = 4;
var
  i: Integer;
  yearStr: String;
  myYear: Integer;
begin
  yList.Clear;
  for i := 1 to Length(str) - YEAR_LENGTH+1 do
  begin
    yearStr := Copy(str, i, YEAR_LENGTH);
    if
       (StrToIntDef(Copy(yearStr, 1, 2),0) in [19, 20]) then
      yList.Add(yearStr)
  end;
end;

Оптимально! smile

Автор: Akella 13.9.2009, 09:08
Цитата(Alexeis @  12.9.2009,  19:30 Найти цитируемый пост)
Нагугли компонентик такой. 

http://forum.vingrad.ru/index.php?showtopic=258533&view=findpost&p=1863448

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)