What is the simplest way to remove multiple spaces in a string in Delphi?

247 views Asked by At

Let's say my string is:

"The   fox   jumped   over    the log."

It should then be turned into:

"The fox jumped over the log."

What is the simplest (1-3 lines) to achieve this, without looping and splitting the string apart?

7

There are 7 answers

3
mjn On

Without loops:

Result := StringReplace(StringReplace(S, '   ', ' ', [rfReplaceAll]), '  ', ' ', [rfReplaceAll]);

Explanation:

  • it first replaces all occurrences of three consecutive spaces with one space
  • then replaces all occurrences of two consecutive spaces with one space

Alternative (untested):

Result := String.Join(' ', StrUtils.SplitString(S, ' '));
0
Remy Lebeau On

The Delphi RTL simply does not have any functions for collapsing consecutive spaces. You will just have to write your own loop for this, eg:

// this is just an example, there are many
// different ways you can implement this
// more efficiently, ie using a TStringBuilder,
// or even modifying the String in-place...
function CollapseSpaces(const S: string): string;
var
  P: PChar;
  AddSpace: Boolean;
begin
  Result := '';
  AddSpace := False;
  P := PChar(S);
  while P^ <> #0 do
  begin
    while CharInSet(P^, [#1..' ']) do Inc(P);
    if P^ = #0 then Exit;
    if AddSpace then
      Result := Result + ' '
    else
      AddSpace := True;
    repeat
      Result := Result + P^;
      Inc(P);
    until P^ <= ' ';
  end;
end;
var S: String;
S := 'The   fox   jumped   over    the log.'
S := CollapseSpaces(S);
1
Andre Ruebel On

This is a one-liner...

  WHILE (pos('  ', s) > 0) DO s := StringReplace(s, '  ', ' ', [rfReplaceAll]);

...which however will become a two-liner after code formatting. And it uses a loop which is somewhat againt the question.

0
Marco van de Voort On

Since you have Free Pascal in the tags, use DelSpace1():

DelSpace1 returns a copy of S with all sequences of spaces reduced to 1 space.

The DelSpace1 implementation is probably also more efficient than the other options presented here, but uses some FPC intrinsics for multiplatform performance(equivalent to assembler scasb/w etc)

4
Boulat Salimov On
str := string.Join(' ','The   fox   jumped   over    the log.'.Split([' '], TStringSplitOptions.ExcludeEmpty));
0
Walter Verhoeven On

If I were to answer, I would try to be as efficient as possible and not create a "one-liner," as it likely doesn't do what you expect. I know you mention not looping, but for those who see your question and do not mind looping, I would do the following:

uses
  System.SysUtils, System.RegularExpressions;

function RemoveExcessiveSpaces(const Input: string): string;
begin
  Result := TRegEx.Replace(Input, '\s+', ' ').Trim;
end;

A regex is looping, just not by you in your code, and without regex I would do:

function RemoveExcessiveSpaces(const Input: string): string;
var
  i, StartIndex, EndIndex: Integer;
  sb: TStringBuilder;
begin
  StartIndex := 1;
  EndIndex := Length(Input);

  // Find the first non-space character
  while (StartIndex <= EndIndex) and (Input[StartIndex] = ' ') do
    Inc(StartIndex);

  // Find the last non-space character
  while (EndIndex >= StartIndex) and (Input[EndIndex] = ' ') do
    Dec(EndIndex);

  // Exit if the string is empty or all spaces
  if StartIndex > EndIndex then
    Exit('');

  sb := TStringBuilder.Create(EndIndex - StartIndex + 1);
  try
    for i := StartIndex to EndIndex do
    begin
      // Append current character if it's not a space or if it's a single space between words
      if (Input[i] <> ' ') or ((i > StartIndex) and (Input[i - 1] <> ' ')) then
        sb.Append(Input[i]);
    end;

    Result := sb.ToString;
  finally
    sb.Free;
  end;
end;
0
ToyGavy On

In the Delphi Programming Language, you can use the StringReplace function from the SysUtils unit to replace multiple spaces with a single space. However, StringReplace only works on one occurrence at a time. To remove all instances of multiple spaces without looping, you can use a regular expression with the TRegEx class from the System.RegularExpressions unit.

Here's a simple way to do it in one line:

uses System.RegularExpressions;

// ...

ResultString := TRegEx.Replace(InputString, '\s+', ' ');

This line of code will replace all sequences of one or more whitespace characters (\s+) in InputString with a single space, and store the result in ResultString. Remember to add System.RegularExpressions to your uses clause to access the TRegEx class.

Thank you for taking the time to view my post. I appreciate your attention and assistance!