Как преобразовать строку в массив в Delphi?

В php и java есть функция взрыва и токенизатора для преобразования строки в массив без знаков препинания. Это функции или какой-то способ в Delphi для выполнения работы. Допустим есть большой файл "Это большой файл со знаками препинания, и пробелами и цифрами 123..." Как нам получить массив "Это большой файл со знаками препинания и пробелами и цифрами 123"

Заранее большое спасибо.

Да, нам нужны только [0..9],[a..z],[A..Z], как \w в регулярном выражении. Можем ли мы использовать регулярное выражение в Tperlregex для извлечения \w и помещения их в Tstringlist, как если бы tstringlist был массивом, но это может быть не так эффективно? Спасибо.


person Dylan    schedule 22.10.2010    source источник
comment
Возможно, вы захотите обратить внимание на тот факт, что строка, по сути, является массивом символов.   -  person Andreas Rejbrand    schedule 22.10.2010
comment
Судя по вашему примеру, вы просто хотите удалить запятые из строки. Не могли бы вы отредактировать свой вопрос, чтобы быть более точным?   -  person Rob Kennedy    schedule 22.10.2010
comment
Спасибо Андреасу Рейбранду и Юджину Маевски.   -  person Dylan    schedule 22.10.2010


Ответы (3)


Если вам нужна функция, которая принимает строку и возвращает массив строк, причем эти строки являются подстроками оригинала, разделенными знаками препинания, как предложил Юджин в моем предыдущем ответе, вы можете сделать

type
  StringArray = array of string;
  IntegerArray = array of integer;
  TCharSet = set of char;

function split(const str: string; const delims: TCharSet): StringArray;
var
  SepPos: IntegerArray;
  i: Integer;
begin
  SetLength(SepPos, 1);
  SepPos[0] := 0;
  for i := 1 to length(str) do
    if str[i] in delims then
    begin
      SetLength(SepPos, length(SepPos) + 1);
      SepPos[high(SepPos)] := i;
    end;
  SetLength(SepPos, length(SepPos) + 1);
  SepPos[high(SepPos)] := length(str) + 1;
  SetLength(result, high(SepPos));
  for i := 0 to high(SepPos) -  1 do
    result[i] := Trim(Copy(str, SepPos[i] + 1, SepPos[i+1] - SepPos[i] - 1));
end;

Пример:

const
  PUNCT = ['.', ',', ':', ';', '-', '!', '?'];

procedure TForm4.FormCreate(Sender: TObject);
var
  str: string;
begin
  for str in split('this, is, a! test!', PUNCT) do
    ListBox1.Items.Add(str)
end;
person Andreas Rejbrand    schedule 22.10.2010

Это зависит от определения «буквенно-цифрового символа» и «знака пунктуации».

Если мы, например, определим набор знаков пунктуации

const
  PUNCT = ['.', ',', ':', ';', '-', '!', '?'];

и считайте все остальные символы буквенно-цифровыми, тогда вы можете сделать

function RemovePunctuation(const Str: string): string;
var
  ActualLength: integer;
  i: Integer;
const
  PUNCT = ['.', ',', ':', ';', '-', '!', '?'];
begin
  SetLength(result, length(Str));
  ActualLength := 0;
  for i := 1 to length(Str) do
    if not (Str[i] in PUNCT) then
    begin
      inc(ActualLength);
      result[ActualLength] := Str[i];
    end;
  SetLength(result, ActualLength);
end;

Эта функция превращает строку в строку. Если вы хотите вместо этого превратить строку в массив символов, просто выполните

type
  CharArray = array of char;

function RemovePunctuation(const Str: string): CharArray;
var
  ActualLength: integer;
  i: Integer;
const
  PUNCT = ['.', ',', ':', ';', '-', '!', '?'];
begin
  SetLength(result, length(Str));
  ActualLength := 0;
  for i := 1 to length(Str) do
    if not (Str[i] in PUNCT) then
    begin
      result[ActualLength] := Str[i];
      inc(ActualLength);
    end;
  SetLength(result, ActualLength);
end;

(Да, в Delphi строки используют индексацию на основе 1, тогда как массивы используют индексацию на основе 0. Это по историческим причинам.)

person Andreas Rejbrand    schedule 22.10.2010
comment
Я считаю, что OP нужна функция синтаксического анализатора, которая будет принимать строку и создавать массив подстрок, извлеченных путем разделения на знаки препинания. - person Eugene Mayevski 'Callback; 22.10.2010
comment
Ах я вижу. (Но почему он/она так не сказал?) - person Andreas Rejbrand; 22.10.2010

Кажется, что встроенной функциональности, как в токенизаторе Java, нет. Давным-давно мы написали класс токенизатора, аналогичный классу Java, который стал частью набора компонентов ElPack (теперь LMD ElPack). Вот некоторая реализация токенизатора строк, похожая на Java one (только что нашел эту ссылку в Google, поэтому я не могу комментировать качество кода).

person Eugene Mayevski 'Callback    schedule 22.10.2010