Разделите строку на массив строк на основе разделителя

Я пытаюсь найти функцию Delphi, которая разделит входную строку на массив строк на основе разделителя. Я нашел много на Google, но у всех, кажется, есть их собственные проблемы, и я не смог заставить любого из них работать.

Я просто должен разделить строку как: "word:doc,txt,docx" в массив на основе ':'. Результат был бы ['word', 'doc,txt,docx'].

У кого-либо есть функция, что они знают работы?

Спасибо

79
задан bluish 23 January 2013 в 16:03
поделиться

5 ответов

вы можете использовать свойство TStrings.DelimitedText для разделения строки

проверить этот образец

program Project28;

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils;

procedure Split(Delimiter: Char; Str: string; ListOfStrings: TStrings) ;
begin
   ListOfStrings.Clear;
   ListOfStrings.Delimiter       := Delimiter;
   ListOfStrings.StrictDelimiter := True; // Requires D2006 or newer.
   ListOfStrings.DelimitedText   := Str;
end;


var
   OutPutList: TStringList;
begin
   OutPutList := TStringList.Create;
   try
     Split(':', 'word:doc,txt,docx', OutPutList) ;
     Writeln(OutPutList.Text);
     Readln;
   finally
     OutPutList.Free;
   end;
end.

ОБНОВЛЕНИЕ

См. Эту ссылку для объяснения StrictDelimiter .

79
ответ дан 24 November 2019 в 10:02
поделиться

Подобна функции Explode () , предлагаемой Mef, но с парой отличий (одно из которых я считаю исправлением ошибки):

  type
    TArrayOfString = array of String;


  function SplitString(const aSeparator, aString: String; aMax: Integer = 0): TArrayOfString;
  var
    i, strt, cnt: Integer;
    sepLen: Integer;

    procedure AddString(aEnd: Integer = -1);
    var
      endPos: Integer;
    begin
      if (aEnd = -1) then
        endPos := i
      else
        endPos := aEnd + 1;

      if (strt < endPos) then
        result[cnt] := Copy(aString, strt, endPos - strt)
      else
        result[cnt] := '';

      Inc(cnt);
    end;

  begin
    if (aString = '') or (aMax < 0) then
    begin
      SetLength(result, 0);
      EXIT;
    end;

    if (aSeparator = '') then
    begin
      SetLength(result, 1);
      result[0] := aString;
      EXIT;
    end;

    sepLen := Length(aSeparator);
    SetLength(result, (Length(aString) div sepLen) + 1);

    i     := 1;
    strt  := i;
    cnt   := 0;
    while (i <= (Length(aString)- sepLen + 1)) do
    begin
      if (aString[i] = aSeparator[1]) then
        if (Copy(aString, i, sepLen) = aSeparator) then
        begin
          AddString;

          if (cnt = aMax) then
          begin
            SetLength(result, cnt);
            EXIT;
          end;

          Inc(i, sepLen - 1);
          strt := i + 1;
        end;

      Inc(i);
    end;

    AddString(Length(aString));

    SetLength(result, cnt);
  end;

Различия:

  1. Параметр aMax ограничивает количество строк, которые должны быть возвращены
  2. Если входная строка заканчивается разделителем, то считается, что существует номинальная «пустая» конечная строка

Примеры:

SplitString(':', 'abc') returns      :    result[0]  = abc

SplitString(':', 'a:b:c:') returns   :    result[0]  = a
                                          result[1]  = b
                                          result[2]  = c
                                          result[3]  = <empty string>

SplitString(':', 'a:b:c:', 2) returns:    result[0]  = a
                                          result[1]  = b

Это конечный разделитель и условный «пустой конечный элемент», который Считаю ошибку исправлением.

Я также включил изменение распределения памяти, которое я предложил, с уточнением (я ошибочно предположил, что входная строка может содержать не более 50% разделителей, но, возможно, она, конечно, может состоять из строк разделителей на 100%, что дает массив пустых элементов! )

13
ответ дан 24 November 2019 в 10:02
поделиться

Я всегда использую что-то подобное:

Uses
   StrUtils, Classes;

Var
  Str, Delimiter : String;
begin
  // Str is the input string, Delimiter is the delimiter
  With TStringList.Create Do
  try
    Text := ReplaceText(S,Delim,#13#10);

    // From here on and until "finally", your desired result strings are
    // in strings[0].. strings[Count-1)

  finally
    Free; //Clean everything up, and liberate your memory ;-)
  end;

end;
15
ответ дан 24 November 2019 в 10:02
поделиться

Вы можете использовать StrUtils.SplitString .

function SplitString(const S, Delimiters: string): TStringDynArray;

Его описание из документации :

Разбивает строку на различные части, разделенные указанными символами-разделителями .

SplitString разбивает строку на разные части, разделенные указанными символами-разделителями. S - это строка, которую нужно разделить. Разделители - это строка, содержащая символы, определенные как разделители.

SplitString возвращает массив строк типа System.Types.TStringDynArray , который содержит разделенные части исходной строки .

44
ответ дан 24 November 2019 в 10:02
поделиться

Здесь представляет собой реализацию функции разнесения, которая доступна во многих других языках программирования как стандартная функция:

type 
  TStringDynArray = array of String;

function Explode(const Separator, S: string; Limit: Integer = 0): TStringDynArray; 
var 
  SepLen: Integer; 
  F, P: PChar; 
  ALen, Index: Integer; 
begin 
  SetLength(Result, 0); 
  if (S = '') or (Limit < 0) then Exit; 
  if Separator = '' then 
  begin 
    SetLength(Result, 1); 
    Result[0] := S; 
    Exit; 
  end; 
  SepLen := Length(Separator); 
  ALen := Limit; 
  SetLength(Result, ALen); 

  Index := 0; 
  P := PChar(S); 
  while P^ <> #0 do 
  begin 
    F := P; 
    P := AnsiStrPos(P, PChar(Separator)); 
    if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then P := StrEnd(F); 
    if Index >= ALen then 
    begin 
      Inc(ALen, 5); 
      SetLength(Result, ALen); 
    end; 
    SetString(Result[Index], F, P - F); 
    Inc(Index); 
    if P^ <> #0 then Inc(P, SepLen); 
  end; 
  if Index < ALen then SetLength(Result, Index); 
end; 

Пример использования:

var
  res: TStringDynArray;
begin
  res := Explode(':', yourString);
5
ответ дан 24 November 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: