Использование SysUtils.WrapText() со строками, содержащими одинарные кавычки

#delphi #escaping #word-wrap #delphi-2007

#delphi #экранирование #перенос слов #delphi-2007

Вопрос:

Я пытаюсь использовать SysUtils.WrapText() функцию со строкой, содержащей символы, заключенные в экранированные одинарные кавычки, и получаю неожиданный результат.

 var
  Lines : TStrings;
begin
  Lines := TStringList.Create;
  try
    Lines.Text := WrapText('Can''t format message, message file not found', 15);
    ShowMessage(Lines.Text);
  finally
    Lines.Free;
  end;
end;
  

Кажется, что функция вообще не переносит строку, если строка содержит символ апострофа.

Я также пытался использовать #39 код вместо символа в одинарных кавычках, но проблема не устранена. Кроме того, я проверил, Lines.Count и это 1 .

изображение

Я попытался удалить символ одинарной кавычки:

 var
  Lines : TStrings;
begin
  Lines := TStringList.Create;
  try
    Lines.Text := WrapText('Cant format message, message file not found', 15);
    ShowMessage(Lines.Text);
  finally
    Lines.Free;
  end;
end;
  

И он начал обертывать строку, как и ожидалось:

изображение

Мне интересно, почему это происходит, и как я должен использовать WrapText() функцию с такими строками?

Комментарии:

1. Похоже, что он не разбивает / игнорирует текст между кавычками. Добавьте еще одну кавычку, и она начнет разделять текст.

2. вы пробовали Lines.Text := WrapText('Cant format message, message file not found', [' '], 15); ?

3. @Sam: Это меняет смысл текста. Can't это сокращение от can not , в то время как cant — наклонная или скошенная поверхность. 🙂

Ответ №1:

То, что вы описываете, является преднамеренным поведением.

В Delphi XE и более ранних версиях документация WrapText() включала это утверждение:

WrapText не вставляет разрыв во встроенную строку, заключенную в кавычки (поддерживаются как одинарные, так и двойные кавычки).

В Delphi XE2 и далее этот оператор исключен из документации, но поведение по-прежнему реализовано в RTL.

Я открыл запрос в Embarcadero по поводу этого упущения:

RSP-24114: В документации WrapText отсутствует важное положение о встроенных строках в кавычках

Комментарии:

1. Спасибо за объяснение, поэтому он видит часть после одинарной кавычки, как если бы это была встроенная строка, заключенная в кавычки…. Знаете ли вы какую-либо альтернативную функцию WrapText ?

2. @Fabrizio Я этого не делаю. Вероятно, вам придется создать свою собственную реализацию или найти стороннюю реализацию, которая не пропускает встроенные строки, заключенные в кавычки.

Ответ №2:

В 10.3.1 исходный код включает код для обработки символов кавычек, как двойных, так и одинарных, который, похоже, просто игнорирует текст между ними. Таким образом, одним из решений было бы использовать апостроф, отличный от символа одиночной кавычки. Вторым было бы избежать использования сокращений. Начало исходного кода функции:

 function WrapText(const Line, BreakStr: string; const BreakChars: TSysCharSet;
  MaxCol: Integer): string;
const
  QuoteChars = ['''', '"'];
  FirstIndex = Low(string);
  StrAdjust = 1 - Low(string);
var
...
  

Один из вариантов:

     Lines.Text := WrapText('Can`t format message, message file not found', 15);
  

Второй вариант:

     Lines.Text := WrapText('Cannot format message, message file not found', 15);