How to iterate over multiline strings in Go

If you need to iterate over each line of a string in Go, you can use the bufio.Scanner type which provides a convenient interface for reading data such as newline-delimited lines of text from a file or some other source.

The way to create a Scanner from a multiline string is by using bufio.NewScanner which takes in an io.Reader interface. The way to create an io.Reader from a string is by using the strings.NewReader method.

Once you have a Scanner, you can call the Scan() method to advance to the next line which can be accessed through the Text() method. Scan() returns a boolean each time it is called. It will return false if there are no more lines.

func main() {
	str := `<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <script></script>
  </body>
</html>`

	scanner := bufio.NewScanner(strings.NewReader(str))

	for scanner.Scan() {
		line := scanner.Text()
		fmt.Println(line)
	}

	if scanner.Err() != nil {
		log.Println(scanner.Err())
	}
}
Run code snippet on the Go playground
Output
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <script></script>
  </body>
</html>

The for loop above will continue until the Scan() method returns false. Each time Scan() is invoked, the next line is accessed using scanner.Text() and printed to the standard output.

Errors must be handled by checking if scanner.Err() is not equal to nil. It returns the first non-EOF error that was encountered by the Scanner.

Thanks for reading, and happy coding!