Parsing & Formatting
Parsing and formatting are common tasks when working with data.
Number Parsing
Go provides functions like strconv package for parsing strings to other types.
package main
import (
"fmt"
"strconv"
)
func main() {
// Parse string to integer
numStr := "42"
num, err := strconv.Atoi(numStr)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Parsed Integer:", num)
// Parse string to float
floatStr := "3.14"
floatNum, err := strconv.ParseFloat(floatStr, 64)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Parsed Float:", floatNum)
// Parse string to integer with base
hexStr := "1a"
num2, err := strconv.ParseInt(hexStr, 16, 64)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Parsed Hex Integer:", num2) // => 26
}
ParseInt
function’s signature is func ParseInt(s string, base int, bitSize int) (i int64, err error)
.
If the base
argument is 0, the true base is implied by the string's prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise.
The bitSize
argument specifies the integer type that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 correspond to int, int8, int16, int32, and int64.
URL Parsing
URL parsing in Go is typically done using the net/url
package. The net/url
package provides a URL type and functions to parse and manipulate URLs.
package main
import (
"fmt"
"net/url"
)
func main() {
// Example URL
rawURL := "https://www.example.com:8080/path?query1=value1&query2=value2#fragment"
// Parse the raw URL
parsedURL, err := url.Parse(rawURL)
if err != nil {
fmt.Println("Error parsing URL:", err)
return
}
// Access various components of the parsed URL
fmt.Println("Scheme:", parsedURL.Scheme)
fmt.Println("Host:", parsedURL.Host)
fmt.Println("Port:", parsedURL.Port())
fmt.Println("Path:", parsedURL.Path)
fmt.Println("RawQuery:", parsedURL.RawQuery)
fmt.Println("Fragment:", parsedURL.Fragment)
// Parse query parameters
queryParams, err := url.ParseQuery(parsedURL.RawQuery)
if err != nil {
fmt.Println("Error parsing query parameters:", err)
return
}
// Access individual query parameters
fmt.Println("Query Parameters:")
for key, values := range queryParams {
for _, value := range values {
fmt.Printf("%s: %s\n", key, value)
}
}
}
Its output:
Scheme: https
Host: www.example.com:8080
Port: 8080
Path: /path
RawQuery: query1=value1&query2=value2
Fragment: fragment
Query Parameters:
query1: value1
query2: value2
Time Parsing / Formatting
The time
package provides functionality for parsing and formatting time.
Parsing
package main
import (
"fmt"
"time"
)
func main() {
// Parse a date string
dateStr := "2017-12-07"
parsedDate, err := time.Parse("2006-01-02", dateStr)
if err != nil {
fmt.Println("Error parsing date:", err)
return
}
fmt.Println("Parsed Date:", parsedDate)
// => Parsed Date: 2017-12-07 00:00:00 +0000 UTC
// Parse a time string with a specific format
timeStr := "15:04:05"
parsedTime, err := time.Parse(timeStr, "12:30:45")
if err != nil {
fmt.Println("Error parsing time:", err)
return
}
fmt.Println("Parsed Time:", parsedTime)
// => Parsed Time: 0000-01-01 12:30:45 +0000 UTC
}
Formatting
package main
import (
"fmt"
"time"
)
func main() {
// Format the current time
currentTime := time.Date(2017, time.October, 15, 13, 36, 28, 0, time.UTC)
formattedTime := currentTime.Format("Monday, January 2, 2006 15:04:05")
fmt.Println("Formatted Time:", formattedTime)
// => Formatted Time: Sunday, October 15, 2017 13:36:28
// Custom formatting
customFormat := "02-Jan-2006 15:04:05"
customFormattedTime := currentTime.Format(customFormat)
fmt.Println("Custom Formatted Time:", customFormattedTime)
// => Custom Formatted Time: 15-Oct-2017 13:36:28
}
Templates
Text Templates
The text/template
package is used for text-based templates.
package main
import (
"bytes"
"fmt"
"text/template"
)
// User struct for template data
type User struct {
Name string
Email string
}
func main() {
// Define a simple template
const templateString = "Hello, {{.Name}}! Your email is {{.Email}}.\n"
// Create a new template and parse the template string
tmpl, err := template.New("greeting").Parse(templateString)
if err != nil {
panic(err)
}
// Create a User instance with data
user := User{
Name: "Lite Rank",
Email: "literank@example.com",
}
// Use a buffer to capture the template output
var resultBuffer bytes.Buffer
// Apply the template to the User instance and capture the result in the buffer
err = tmpl.Execute(&resultBuffer, user)
if err != nil {
panic(err)
}
// Convert the buffer to a string and print the result
resultString := resultBuffer.String()
fmt.Println(resultString)
// => Hello, Lite Rank! Your email is literank@example.com.
}
HTML Templates
The html/template
package is used for HTML-based templates.
package main
import (
"bytes"
"fmt"
"html/template"
)
// User struct for template data
type User struct {
Name string
Email string
}
func main() {
// Define an HTML template
const templateHTML = `
<!DOCTYPE html>
<html>
<head>
<title>Greeting Page</title>
</head>
<body>
<h1>Hello, {{.Name}}!</h1>
<p>Your email is {{.Email}}.</p>
</body>
</html>`
// Create a new template and parse the HTML template string
tmpl, err := template.New("greeting").Parse(templateHTML)
if err != nil {
panic(err)
}
// Create a User instance with data
user := User{
Name: "Lite Rank",
Email: "lr@example.com",
}
var resultBuffer bytes.Buffer
err = tmpl.Execute(&resultBuffer, user)
if err != nil {
panic(err)
}
fmt.Println(resultBuffer.String())
}
Code Challenge
Write a Go program that reads a CSV (Comma-Separated Values) file and performs the following tasks:
- Parse the CSV data into a structured data format (e.g., a slice of structs).
- Print the parsed data in a human-readable format.