-1

I've the below text:

str := `
 

Maybe we should all just listen to
records and quit our jobs

— gach White —

AZ QUOTES

 

 

 `

And want to remove ALL empty lines. I was able to remove the empty lines in the paragraphs as:

str = strings.Replace(str, "\n\n", "\n", -1)
fmt.Println(str)

And ended up with:

 
Maybe we should all just listen to
records and quit our jobs
— gach White —
AZ QUOTES




So, still have couple of empty lines at the beginning and few empty lines at the end, how can I get red of them?

In my app I'm trying to extract the texts from all "png" files in the same directory, and get it in pretty format, my full code so far is:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "os/exec"
    "path/filepath"
    "strings"

    _ "image/png"
)

func main() {
    var files []string

    root := "."
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if filepath.Ext(path) == ".png" {
            path = strings.TrimSuffix(path, filepath.Ext(path))
            files = append(files, path)
        }
        return nil
    })
    if err != nil {
        panic(err)
    }
    for _, file := range files {
        fmt.Println(file)

        err = exec.Command(`tesseract`, file+".png", file).Run()
        if err != nil {
            fmt.Printf("Error: %s\n", err)
        } else {
            b, err := ioutil.ReadFile(file + ".txt") // just pass the file name
            if err != nil {
                fmt.Print(err)
            } else {
                str := string(b) // convert content to a 'string'
                str = strings.Replace(str, "\n\n", "\n", -1)
                fmt.Println(str) // print the content as a 'string'
            }
        }
    }

}
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203

5 Answers5

2

split the string with \n and remove whitespaces in splitted eliments and then concat them with \n

func trimEmptyNewLines(str string) string{
    strs := strings.Split(str, "\n")
    str = ""
    for _, s := range strs {
        if len(strings.TrimSpace(s)) == 0 {
            continue
        }
        str += s+"\n"
    }
    str = strings.TrimSuffix(str, "\n")

    return str
}

run full code here

nipuna
  • 3,697
  • 11
  • 24
1

You can use strings.TrimSpace to remove all leading and trailing whitespace:

str = strings.TrimSpace(str)
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • Thanks, but did not work, it just removed the leading trailing space. – Hasan A Yousef Jul 29 '21 at 18:17
  • Why not? It worked for me: https://play.golang.org/p/3FkkYfMFYuK – mkrieger1 Jul 29 '21 at 18:19
  • Or `TrimSpace` to remove all leading and trailing whitespace? – JimB Jul 29 '21 at 18:22
  • Once I added `fmt.Printf("%q\n", str)` I got: `"Maybe we should all just listen to\nrecords and quit our jobs\n— gach White —\nAZ QUOTES\n \n \n \n\f"`, before it was: `" \n\nMaybe we should all just listen to\nrecords and quit our jobs\n\n— gach White —\n\nAZ QUOTES\n\n \n\n \n\n \n\f"` – Hasan A Yousef Jul 29 '21 at 18:22
  • 1
    Well, your string contains `\f` which presumably `TrimSpace` will catch. Thanks, @JimB – mkrieger1 Jul 29 '21 at 18:23
0

It looks like you have white space inbetween, e.g.

\n \n

So, doing a regexp replace with regular expression \n[ \t]*\n might be more sensible.

This won't remove single empty lines at the beginning though, for this you would use ^\n* and replace with an empty string.


Refining this a bit further, you can add more white space like \f and consider multiple empty lines at once

\n([ \t\f]*\n)+
  • \n a newline
  • (...)+ followed by one or more
  • [ \t\f]*\n empty lines

This clears all empty lines in between, but may keep white space at the beginning or the end of the string. As suggested in other answers, adding a strings.TrimSpace() takes care of this.


Putting everything together gives https://play.golang.org/p/E07ZkE2nlcp

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    str := `
 

Maybe we should all just listen to
records and quit our jobs

— gach White —

AZ QUOTES

 

 

 `
    re := regexp.MustCompile(`\n([ \t\f]*\n)+`)
    str = string(re.ReplaceAll([]byte(str), []byte("\n")))
    str = strings.TrimSpace(str)
    fmt.Println("---")
    fmt.Println(str)
    fmt.Println("---")
}

which finally shows

---
Maybe we should all just listen to
records and quit our jobs
— gach White —
AZ QUOTES
---
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
0

I copied your string and turned it into JSON:

package main

import (
    "encoding/json"
    "log"
)

func main() {

    // The string from the original post.
    myString := `
 

Maybe we should all just listen to
records and quit our jobs

— gach White —

AZ QUOTES

 

 

 `

    // Marshal to json.
    data, err := json.Marshal(myString)
    if err != nil {
        log.Fatalf("Failed to marshal string to JSON.\nError: %s", err.Error())
    }

    // Print the string to stdout.
    println(string(data))
}

It'll probably be easier to see the whitespace in JSON.

"\n \n\nMaybe we should all just listen to\nrecords and quit our jobs\n\n— gach White —\n\nAZ QUOTES\n\n \n\n \n\n "

Do you see the problem here? There's a couple of spaces in between your newline characters, additionally, you have uneven numbers of newline characters. so replacing \n\n with \n won't behave as you'd like it to.

I see one of your goals is this:

And want to remove ALL empty lines.

(I'm not addressing extracting text from PNG files, as that's a separate question.)

package main

import (
    "encoding/json"
    "log"
    "strings"
)

func main() {

    // The string from the original post.
    myString := `
 

Maybe we should all just listen to
records and quit our jobs

— gach White —

AZ QUOTES

 

 

 `

    // Create a resulting string.
    result := ""

    // Iterate through the lines in this string.
    for _, line := range strings.Split(myString, "\n") {
        if line = strings.TrimSpace(line); line != "" {
            result += line + "\n"
        }
    }

    // Print the result to stdout.
    println(result)

    // Marshal the result to JSON.
    resultJSON, err := json.Marshal(result)
    if err != nil {
        log.Fatalf("Failed to marshal result to JSON.\nError: %s", err.Error())
    }

    println(string(resultJSON))
}

stdout:

Maybe we should all just listen to
records and quit our jobs
— gach White —
AZ QUOTES

"Maybe we should all just listen to\nrecords and quit our jobs\n— gach White —\nAZ QUOTES\n"
Micah Parks
  • 1,504
  • 1
  • 10
  • 22
0

A little different answer.

package main

import (
    "fmt"
)

func main() {
    str := `
 

Maybe we should all just listen to
records and quit our jobs

— gach White —

AZ QUOTES

 

 

 `    
    first := 0
    last := 0

    for i, j := range []byte(str) {
        if j != 10 && j != 32 {
            if first == 0 {
                first = i
            }
            last = i
        }

    }
    str = str[first : last+1]
    fmt.Print(str)
}
Nick
  • 1,017
  • 1
  • 10
  • 16
  • this solution is neat for its speed, though, OP said in a comment it contained `\f` (i did not know myself, https://stackoverflow.com/a/4334399/4466350). So the solution is also a bit simplistic. –  Jul 29 '21 at 19:27
  • Ohh I did not read that, but to address it we can add another `&& j != 12` to first if. – Nick Jul 29 '21 at 19:38