Go web编程(七——文本处理)
文本包括字符串、数字、Json、XML等等。
原文作者:Go 技术论坛文档:《Go Web 编程()》
转自链接:https://learnku.com/docs/build-web-application-with-golang/077-summary/3201
XML
<?xml version="1.0" encoding="utf-8"?>
<servers version="1">
<server>
<serverName>Shanghai_VPN</serverName>
<serverIP>127.0.0.1</serverIP>
</server>
<server>
<serverName>Beijing_VPN</serverName>
<serverIP>127.0.0.2</serverIP>
</server>
</servers>
- 解析xml
使用xml包中的Unmarshal函数
func Unmarshal(data []byte,v interface{}) error
data用来接收xml数据流,v把xml转换为任意的格式。
例:
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
"os"
)
type Recurlyservers struct {
XMLName xml.Name `xml:"servers"`
Version string `xml:"version,attr"`
Svs []server `xml:"server"`
Description string `xml:",innerxml"`
}
type server struct {
XMLName xml.Name `xml:"server"`
ServerName string `xml:"serverName"`
ServerIP string `xml:"serverIP"`
}
func main() {
file, err := os.Open("servers.xml") // For read access.
if err != nil {
fmt.Printf("error: %v", err)
return
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
fmt.Printf("error: %v", err)
return
}
v := Recurlyservers{}
err = xml.Unmarshal(data, &v) //调用Unmarshal函数
if err != nil {
fmt.Printf("error: %v", err)
return
}
fmt.Println(v)
}
定义与xml匹配的go语言的Struct类型,然后通过xml.Unmarshal来将xml的数据解析成对应的struct对象。
在上面的代码中可以看到类似于xml:"serverName"这样的内容,被称为struct tag,用来辅助反射的。
调用Unmarshal时首先会读取struct tag,如果没有,那么就会对应字段名,大小写敏感。
- 输出xml
xml包中提供了Marshal和MarshalIndent两个函数来满足需求。
区别:MarshalIndent会增加前缀和缩进
func Marshal(v interface{})([]byte,error)
func MarshalIndent(v interface{},prefix,indent string)([]byte,error)
例:
package main
import (
"encoding/xml"
"fmt"
"os"
)
type Servers struct {
XMLName xml.Name `xml:"servers"`
Version string `xml:"version,attr"`
Svs []server `xml:"server"`
}
type server struct {
ServerName string `xml:"serverName"`
ServerIP string `xml:"serverIP"`
}
func main() {
v := &Servers{Version: "1"}
v.Svs = append(v.Svs, server{"Shanghai_VPN", "127.0.0.1"})
v.Svs = append(v.Svs, server{"Beijing_VPN", "127.0.0.2"})
output, err := xml.MarshalIndent(v, " ", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write([]byte(xml.Header))
os.Stdout.Write(output)
}
output:
<?xml version="1.0" encoding="UTF-8"?>
<servers version="1">
<server>
<serverName>Shanghai_VPN</serverName>
<serverIP>127.0.0.1</serverIP>
</server>
<server>
<serverName>Beijing_VPN</serverName>
<serverIP>127.0.0.2</serverIP>
</server>
</servers>
JSON处理
{
"servers": [
{
"serverName": "Shanghai_VPN",
"serverIP": "127.0.0.1"
},
{
"serverName": "Beijing_VPN",
"serverIP": "127.0.0.2"
}
]
}
- 解析到struct
func Unmarshal(data []byte,v interface{}) error
解析:
package main
import (
"encoding/json"
"fmt"
)
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
func main() {
var s Serverslice
str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}`
json.Unmarshal([]byte(str), &s)
fmt.Println(s)
}
- 解析到interface
不知道被解析的数据的格式时。
bool代表JSON booleans,float64代表JSON numbers,string代表JSON strings,nil代表JSON null。
使用simplejson包:
js, err := simplejson.NewJson([]byte(`{
"test": {
"array": [1, "2", 3],
"int": 10,
"float": 5.150,
"bignum": 9223372036854775807,
"string": "simplejson",
"bool": true
}
}`))
arr, _ := js.Get("test").Get("array").Array()
i, _ := js.Get("test").Get("int").Int()
ms := js.Get("test").Get("string").MustString()
- 生成JSON
使用JSON包中的Marshal函数来处理,输出JSON格式的数据。
func Marshal(v interface{})([]byte,error)
package main
import (
"encoding/json"
"fmt"
)
type Server struct {
ServerName string
ServerIP string
}
type Serverslice struct {
Servers []Server
}
func main() {
var s Serverslice
s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"})
s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"})
b, err := json.Marshal(s)
if err != nil {
fmt.Println("json err:", err)
}
fmt.Println(string(b))
}
output:
{"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]}
想要把开头的大写改为小写就要使用struct tag定义来实现
type Server struct {
ServerName string `json:"serverName"`
ServerIP string `json:"serverIP"`
}
type Serverslice struct {
Servers []Server `json:"servers"`
}
Marshal只有在转换成功的时候才会返回数据,在转换的过程中需要注意一下几点:
JSON对象只支持string作为key,所以要编码一个map必须是Map[string] (任意类型)。
Channel,complex和function是不能被编码成JSON的
嵌套的数据是不能编码的,不然会让JSON进入死循环
指针在编码的时候回输出指针指向的内容,而空指针会输出null
正则处理
使用regexp标准包。
func Match(pattern string,b []byte)(matched bool,error error)
func MathReader(parttern string,r io.RuneReader)(matched bool,error error)
func MatchString(parttern string,s string)(matched bool,error error)
实现同一个功能,就是判断Parttern是否与输入源匹配,匹配返回true,如果解析错误返回error。
验证IP地址:
func IsIP(ip string) (b bool) {
if m, _ := regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", ip); !m {
return false
}
return true
}
解析正则表达式的方法:
func Compile(expr string) (*Regexp, error)
func CompilePOSIX(expr string) (*Regexp, error)
func MustCompile(str string) *Regexp
func MustCompilePOSIX(str string) *Regexp
模板
使用template包来进行模板处理。
func handler(w http.ResponseWriter, r *http.Request) {
t := template.New("some template") // 创建一个模板
t, _ = t.ParseFiles("tmpl/welcome.html") // 解析模板文件
user := GetUser() // 获取当前用户信息
t.Execute(w, user) // 执行模板的 merger 操作
}
GO语言模板通过{{}}
来包含需要在渲染时被替换的字段,{{.}}表示当前的对象。如果要访问当前字段通过{{.FileName}}。
文件操作
- 目录操作
OS包
package main
import{
"fmt"
"os"
}
func main(){
os.Mkdir("astaxie",0777)
os.MkdirAll("astaxie/test1/test2",0777)
err := os.Remove("astaxie")
if err != nill {
fmt.Println(err)
}
os.RemoveAll("astaxie")
}
- 建立文件
func Create(name string)(file *File,err Error)
//根据提供的文件名创建新的文件,返回一个文件对象。默认权限0666
func NewFile(fd uintptr,name string)*File
//根据文件描述符创建相应的文件,返回一个文件对象
- 打开文件
func Open(name string)(file *File,err Error)
打开一个名称为name的文件,但是是只读方式,内部实现其实调用了OpenFile
func OpenFile(name string,flag int,perm uint32)(file *File,err Error)
- 写文件函数
func (file *File)Write(b []byte)(n int,err Error)
//写入byte类型的信息到文件
func (file *File)WriteAt(b []byte,off int64)(n int,err Error)
//在指定位置开始写入byte类型的信息
func (file *File)WriteString(s string)(ret int,err Error)
//写入string信息到文件
package main
import(
"fmt"
"os"
)
func main(){
userFile := "astaxie.txt"
fout,err := os.Create(userFile)
if err != nil {
fmt.Println(userFile,err)
return
}
defer fout.Close()
for i := 0;i<10;i++ {
fout.WriteString("Just a test!\r\n")
fout.Write([]byte("Just a test!\r\n"))
}
}
- 读文件函数:
func (file *File)Read(b []byte)(n int,err Error)
读取数据到b中
func (file *File)ReatAt(b []byte,off int64)(n int,err Error)
从off开始读取数据到b中
package main
import(
"fmt"
"os"
)
func main(){
userFile := "asatxie.txt"
fl,err := os.Open(userFile)
if err != nil {
fmt.Println(userFile,err)
return
}
defer fl.Close()
buf := make([]byte,1024)
for {
n,_ := fl.Read(buf)
if 0 == n{
break
}
os.Stdout.Write(buf[:n])
}
}
- 删除文件
func Remove(name string)Error
字符串处理
使用strings包。
func Contains(s,substr string)bool
//判断字符串s手否包含substr,返回bool值。
func Join(a []string,sep string)string
//字符串连接,把slice a通过sep链接起来。
func Index(s,sep string)int
//在字符串s查找sep所在的位置,返回位置值,找不到返回-1
func Repeat(s string,cout int)string
//重复s字符串count次,最后返回重复的字符串
func Replace(s,old,new string,n int)string
//在s字符串中,把old字符串替换为new字符串,n表示替换的次数,小于0表示全部替换
func Split(s,sep string)[]string
//把s字符串按照sep分割,返回slice
func Trim(s string,cutset string)string
//在s字符串的头部和尾部去除cutset指定的字符串
func Fields(s string)[]string
//去除s字符串的空格符,并且按照空格分割返回slice
- 字符串转换
字符串转化的函数在strconv中。
Append
str:=make([]byte,0,100)
str = strconv.AppendInt(str,4567,10)
Format包中函数把其他类型转换为字符串
a := strconv.FormatBool(false)
Parse系列函数把字符串转换为其他类型
a,err := strconv.ParseBool("false")

浙公网安备 33010602011771号