Removing excess blanks

How to remove whitespace inside a string?

Would be in the sense of removing spaces from a text string, with the exception of simple spaces between words. Like Excel's "tidy up" function.

Author: Maniero, 2017-10-02

2 answers

The function AllTrim() solves most cases. If you want it to delete in the Middle:

Function MiddleTrim(cText)
    Local cClean := ""
    Local cLast := " "
    Local nLen := Len(cText)
    Local i
    Local cChar
    For i := 1 To nLen
        cChar := Substr(cText, i, 1)
        If cChar != " "
            cClean += cChar
        ElseIf cLast != " "
            cClean += " "
        EndIf
        cLast := cChar
    Next
    If Substr(cClean, Len(cClean), 1) == " "
        cClean := Substr(cClean, 1, Len(cClean) - 1)
    EndIf
Return cClean

Also I put on GitHub for future reference.

In this way reads character by character identifying if there was a space before, only copies the character if it is not space or if it is the space immediately following a non-space, that is, it remains only one space. As it can get one last space at the end, it cleans up as well. Scroll character by character is what the StrTran() and the AllTrim() would, so it has a chance to be more efficient this way by going through only once.

In Harbour maybe not because it would run in C quite efficiently. I don't know how it is today, but ADVPL had pretty inefficient implementation on many things, so much so that some common features in Harbour or even Clipper even recommend avoiding use.

 9
Author: Maniero, 2020-06-19 14:59:26

An alternative:

Function MiddleTrim(cText)
    While "  " $ cText
        cText = StrTran(cText, "  ", " ")
    End
    Return AllTrim(cText)

Remembering that although shorter than the answer of @Maniero (who has already received my +1), it is not necessarily more performative, since it can go through the string several times.

Points of interest:

  • StrTran(cText, " ", " ") swap occurrences of two spaces for one. But since the function is not recursive, it needs a loop;

  • While " " $ cText loops while " " is contained in cText;

  • Finally AllTrim removes the spaces from the "ends" of the string.

Note:

I took the Harbour syntax as a basis, if there is any difference in Advpl it will probably be just a fit in While .. End. The relevant here is logic.

 6
Author: Bacco, 2017-10-04 02:25:05