Delphi: StringList Delimiter всегда является пробелом, даже если установлен Delimiter

46

У меня возникают проблемы с разделителем в классе TStringList. Посмотрите:

var
  s: string;
  sl: TStringList;

begin
  sl := TStringList.Create;
  s := 'Users^foo bar^bar foo^foobar^barfoo';
  sl.Delimiter := '^';
  sl.DelimitedText := s;
  ShowMessage(sl[1]);
end;

sl[1] ДОЛЖЕН возвращаться 'foo bar'

sl[1] Возвращает 'foo'

Кажется, что теперь разделитель '^' AND ' '

Любые идеи?

  • 0
    В какой версии Delphi вы работаете?
  • 0
    Я работаю над Delpi 7
Показать ещё 2 комментария
Теги:
delphi-7
delimiter
tstringlist

5 ответов

74
Лучший ответ

Вы должны установить s1.StrictDelimiter := True, чтобы пробелы не считались разделителями, подробнее здесь.

Поскольку вы работаете в версии, которая не поддерживает вышеописанную (как было выяснено после отправки ответа), у вас есть два варианта:

  • Поиск знака, который, как вы знаете, не будет использоваться в исходном тексте (например, подчеркивание), преобразовать все пробелы в этот символ перед разбиением и преобразовать обратно после разделения. Это предложение robosoft.
  • Если в тексте нет инвертированных запятых и пробелов, вы можете использовать трюк Alexander и обернуть текст между разделителями в инвертированной команде, чтобы 'hello hello^bye bye' переходит в '"hello hello"^"bye bye"'. Если вы выбрали этот путь, и он работает для вас, пожалуйста, примите ответ Александра, а не мой, он также предоставит код для его реализации.

Оба обхода, не использующие StrictDelimiter, имеют ограничения: для первого требуется некоторый неиспользуемый символ, а второй не требует перевернутых запятых и пробелов в исходном тексте.

Возможно, пришло время перейти на более новую версию Delphi:)

  • 0
    Вот досада! Любая начальная точка обхода?
  • 1
    Что вы хотите обойти? Похоже, решение для меня.
Показать ещё 4 комментария
18
sl.DelimitedText := '"' + StringReplace(S, sl.Delimiter, '"' + sl.Delimiter + '"', [rfReplaceAll]) + '"';
  • 2
    Дерьмо, ты меня избил, я печатал точно такой же ответ :)
  • 0
    Очень умно, спасибо Александр, а также The_Fox, даже если вы не помогли мне напрямую, но собирались это сделать :)
Показать ещё 3 комментария
3

У Ryan есть отличное решение этой проблемы, используя функцию ExtractStrings() в Delphi. См:

Разбор строки с использованием разделителя в TStringList, похоже, также анализирует пробелы (Delphi)

Итак, в вашем случае замените вызовы на sl.Delimiter и sl.DelimitedText на следующую строку: ExtractStrings (['^'], [], PChar (S), sl);

2

Работайте в Delphi 7 "как перчатки" для меня. Это моя функция после применения Alexander Trick:

procedure Split (const Delimiter: Char; Input: string; const Strings: TStrings) ;
begin
   Assert(Assigned(Strings)) ;
   Strings.Clear;
   Strings.Delimiter := Delimiter;
   Strings.DelimitedText :=  '"' + StringReplace(Input, Delimiter, '"' + Delimiter + '"', [rfReplaceAll]) + '"' ;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := 'Users^foo bar^bar foo^foobar^barfoo';
  Split('^',Edit1.Text,Memo1.Lines);
end;

Спасибо большое!

  • 0
    Это обходной путь, а не решение.
2
sl.Text := StringReplace(S, sl.Delimiter, sLineBreak, [rfReplaceAll]);
  • 1
    Вы должны, вероятно, добавить объяснение того, что это делает.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню