• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go标准库的学习-regexp

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

参考:https://studygolang.com/pkgdoc

导入方式:

import "regexp"

regexp包实现了正则表达式搜索。

正则表达式采用RE2语法(除了\c、\C),和Perl、Python等语言的正则基本一致。

参见http://code.google.com/p/re2/wiki/Syntax

 

1)判断是否匹配

下面的三个函数都实现了同一个功能,就是判断pattern是否和输入源匹配,匹配就返回true,如果解析正则出错则返回error。三者的区别在于输入源不同

func Match

func Match(pattern string, b []byte) (matched bool, err error)

Match检查b中是否存在匹配pattern的子序列。更复杂的用法请使用Compile函数和Regexp对象。

func MatchString

func MatchString(pattern string, s string) (matched bool, err error)

MatchString类似Match,但匹配对象是字符串。

func MatchReader

func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)

MatchReader类似Match,但匹配对象是io.RuneReader。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    matched, err := regexp.MatchString("foo.*", "seafood")
    fmt.Println(matched, err)
    matched, err = regexp.MatchString("bar.*", "seafood")
    fmt.Println(matched, err)
    matched, err = regexp.MatchString("a(b", "seafood")
    fmt.Println(matched, err)
}

返回:

userdeMBP:go-learning user$ go run test.go
true
false
userdeMBP:go-learning user$ go run test.go
true <nil>
false <nil>
false error parsing regexp: missing closing ): `a(b`

 

 当然你也可以使用下面的函数,结果是等价的:

type Regexp

type Regexp struct {
    // 内含隐藏或非导出字段
}

Regexp代表一个编译好的正则表达式。Regexp可以被多线程安全地同时使用。

func (*Regexp) Match

func (re *Regexp) Match(b []byte) bool

Match检查b中是否存在匹配pattern的子序列。

func (*Regexp) MatchString

func (re *Regexp) MatchString(s string) bool

MatchString类似Match,但匹配对象是字符串。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    var validID = regexp.MustCompile(`^[a-z]+\[[0-9]+\]$`)
    fmt.Println(validID.MatchString("adam[23]")) //true
    fmt.Println(validID.MatchString("Job[48]")) //false
    fmt.Println(validID.MatchString("snakey")) //false
}

 

func (*Regexp) MatchReader

func (re *Regexp) MatchReader(r io.RuneReader) bool

MatchReader类似Match,但匹配对象是io.RuneReader。

 

2)通过正则获取内容

 Match模式只能用来对字符串的判断,如果想要截取部分字符串、过滤字符串或者提取出符合条件的一批字符串,就应该使用更复杂的方法

1》解析正则表达式的方法有:

func Compile

func Compile(expr string) (*Regexp, error)

Compile解析并返回一个正则表达式。如果成功返回,该Regexp就可用于匹配文本。

在匹配文本时,该正则表达式会尽可能早的开始匹配,并且在匹配过程中选择回溯搜索到的第一个匹配结果。这种模式被称为“leftmost-first”,Perl、Python和其他实现都采用了这种模式,但本包的实现没有回溯的损耗。对POSIX的“leftmost-longest”模式,参见CompilePOSIX。

func CompilePOSIX

func CompilePOSIX(expr string) (*Regexp, error)

类似Compile但会将语法约束到POSIX ERE(egrep)语法,并将匹配模式设置为leftmost-longest。

在匹配文本时,该正则表达式会尽可能早的开始匹配,并且在匹配过程中选择搜索到的最长的匹配结果。这种模式被称为“leftmost-longest”,POSIX采用了这种模式(早期正则的DFA自动机模式)。

然而,可能会有多个“leftmost-longest”匹配,每个都有不同的组匹配状态,本包在这里和POSIX不同。在所有可能的“leftmost-longest”匹配里,本包选择回溯搜索时第一个找到的,而POSIX会选择候选结果中第一个组匹配最长的(可能有多个),然后再从中选出第二个组匹配最长的,依次类推。POSIX规则计算困难,甚至没有良好定义。

参见http://swtch.com/~rsc/regexp/regexp2.html#posix获取细节。

func MustCompile

func MustCompile(str string) *Regexp

MustCompile类似Compile但会在解析失败时panic,主要用于全局正则表达式变量的安全初始化。

func MustCompilePOSIX

func MustCompilePOSIX(str string) *Regexp

MustCompilePOSIX类似CompilePOSIX但会在解析失败时panic,主要用于全局正则表达式变量的安全初始化。

 

上面的函数用于解析正则表达式是否合法,如果正确,则会返回一个Regexp,然后就能够利用该对象在任意字符串上执行需要的操作

带POSIX后缀的不同点在于其使用POSIX语法,该语法使用最长最左方式搜索,而不带该后缀的方法是采用最左方式搜索(如[a-z]{2,4}这样的正则表达式,应用于"aa09aaa88aaaa"这个文本串时,带POSIX后缀的将返回aaaa,不带后缀的则返回aa)。

前缀有Must的函数表示在解析正则表达式时,如果匹配模式串不满足正确的语法则直接panic,而不加Must前缀的将只是返回错误

2》解析完正则表达式后能够进行的操作有

1〉查找操作——即前缀带有Find的函数

func (*Regexp) Find

func (re *Regexp) Find(b []byte) []byte

Find返回保管正则表达式re在b中的最左侧的一个匹配结果的[]byte切片。如果没有匹配到,会返回nil。

func (*Regexp) FindString

func (re *Regexp) FindString(s string) string

Find返回保管正则表达式re在b中的最左侧的一个匹配结果的字符串。如果没有匹配到,会返回"";但如果正则表达式成功匹配了一个空字符串,也会返回""。如果需要区分这种情况,请使用FindStringIndex 或FindStringSubmatch

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
  re := regexp.MustCompile("fo.?")
  fmt.Printf("%q\n", re.FindString("seafood")) //"foo"
  fmt.Printf("%q\n", re.Find([]byte("seafood"))) //"foo"
}

 

下面两个函数跟上面的两个函数的差别在与能够使用第二个参数来决定返回几个匹配结果:

func (*Regexp) FindAll

func (re *Regexp) FindAll(b []byte, n int) [][]byte

Find返回保管正则表达式re在b中的所有不重叠的匹配结果的[][]byte切片。如果没有匹配到,会返回nil。

func (*Regexp) FindAllString

func (re *Regexp) FindAllString(s string, n int) []string

Find返回保管正则表达式re在b中的所有不重叠的匹配结果的[]string切片。如果没有匹配到,会返回nil。

 举例:
package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a.")
    fmt.Println(re.FindAllString("paranormal", -1)) //-1表示返回所有匹配的值,[ar an al]
    fmt.Println(re.FindAllString("paranormal", 2)) //2表示返回2个匹配的值,[ar an]
    fmt.Println(re.FindAllString("paranormal", 1)) //1表示返回1个匹配的值,[ar]
    fmt.Println(re.FindAllString("paranormal", 0)) //0表示返回0个匹配的值,[]
    fmt.Println(re.FindAllString("graal", -1)) //[aa]
    fmt.Println(re.FindAllString("none", -1)) //[]
}

 

下面三个函数的作用是查找索引:

func (*Regexp) FindIndex

func (re *Regexp) FindIndex(b []byte) (loc []int)

Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以通过起止位置对b做切片操作得到:b[loc[0]:loc[1]]。如果没有匹配到,会返回nil。

func (*Regexp) FindStringIndex

func (re *Regexp) FindStringIndex(s string) (loc []int)

Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以通过起止位置对b做切片操作得到:b[loc[0]:loc[1]]。如果没有匹配到,会返回nil。

func (*Regexp) FindReaderIndex

func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int)

Find返回保管正则表达式re在b中的最左侧的一个匹配结果的起止位置的切片(显然len(loc)==2)。匹配结果可以在输入流r的字节偏移量loc[0]到loc[1]-1(包括二者)位置找到。如果没有匹配到,会返回nil。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("ab?")
    fmt.Println(re.FindStringIndex("tablett")) //[1 3],表示匹配到的字符在"tablett"的[1,3]切片处
    fmt.Println(re.FindStringIndex("foo") == nil) //没有匹配到会返回nil
    fmt.Println(re.FindIndex([]byte("tablett"))) //[1 3],表示匹配到的字符在"tablett"的[1,3]切片处
    fmt.Println(re.FindIndex([]byte("foo")) == nil) //没有匹配到会返回nil
}

下面两个函数和上面的函数的区别在与能够使用第二个参数决定返回匹配的数量:

func (*Regexp) FindAllIndex

func (re *Regexp) FindAllIndex(b []byte, n int) [][]int

Find返回保管正则表达式re在b中的所有不重叠的匹配结果的起止位置的切片。如果没有匹配到,会返回nil。

func (*Regexp) FindAllStringIndex

func (re *Regexp) FindAllStringIndex(s string, n int) [][]int

Find返回保管正则表达式re在b中的所有不重叠的匹配结果的起止位置的切片。如果没有匹配到,会返回nil。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a.")
    fmt.Println(re.FindAllStringIndex("paranormal", -1)) //[[1 3] [3 5] [8 10]],-1表示匹配全部
    fmt.Println(re.FindAllStringIndex("paranormal", 2)) //[[1 3] [3 5]] ,2表示返回匹配的两个的索引切片
    fmt.Println(re.FindAllStringIndex("paranormal", 1)) //[[1 3]] ,1表示返回匹配的一个的索引切片
    fmt.Println(re.FindAllIndex([]byte("paranormal"), -1)) //[[1 3] [3 5] [8 10]]
    fmt.Println(re.FindAllIndex([]byte("paranormal"), 2)) //[[1 3] [3 5]]
    fmt.Println(re.FindAllIndex([]byte("paranormal"), 1)) //[[1 3]]
}

 

下面两个函数使用在正则表达式有分组时,切片中的第一个索引值为整个输入字符串满足正则表达式的输出,后面的索引值则为满足分组的字符串:

func (*Regexp) FindSubmatch

func (re *Regexp) FindSubmatch(b []byte) [][]byte

Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的[][]byte切片。如果没有匹配到,会返回nil。

func (*Regexp) FindStringSubmatch

func (re *Regexp) FindStringSubmatch(s string) []string

Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的[]string切片。如果没有匹配到,会返回nil。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b(y|z)c")
    fmt.Printf("%q\n", re.FindSubmatch([]byte("-axxxbyc-"))) //["axxxbyc" "xxx" "y"]
    fmt.Printf("%q\n", re.FindSubmatch([]byte("-abzc-"))) //["abzc" "" "z"]
    fmt.Printf("%q\n", re.FindSubmatch([]byte("-aczc-"))) //[],整个都不匹配,更没有分组匹配,将返回空数组
    fmt.Printf("%q\n", re.FindStringSubmatch("-axxxbyc-")) //["axxxbyc" "xxx" "y"]
    fmt.Printf("%q\n", re.FindStringSubmatch("-abzc-")) //["abzc" "" "z"]
    fmt.Printf("%q\n", re.FindStringSubmatch("-aczc-")) //[],整个都不匹配,更没有分组匹配,将返回空数组
}

下面两个函数和上面两个函数的区别在与能够使用第二个参数决定返回匹配的数量:

func (*Regexp) FindAllSubmatch

func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte

Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的[][][]byte切片。如果没有匹配到,会返回nil。

func (*Regexp) FindAllStringSubmatch

func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string

Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的[][]string切片。如果没有匹配到,会返回nil。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b(y|z)c")
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-axxxbyc-axxbyc-axbyc-"), -1)) //[["axxxbyc" "xxx" "y"] ["axxbyc" "xx" "y"] ["axbyc" "x" "y"]]
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-axxxbyc-axxbyc-axbyc-"), 2)) //[["axxxbyc" "xxx" "y"] ["axxbyc" "xx" "y"]]
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-axxxbyc-axxbyc-axbyc-"), 1)) //[["axxxbyc" "xxx" "y"]]
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-abzc-abzc-"), -1)) //[["abzc" "" "z"] ["abzc" "" "z"]]
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-abzc-abzc-"), 1)) //[["abzc" "" "z"]]
    fmt.Printf("%q\n", re.FindAllSubmatch([]byte("-aczc-"), -1)) //[],整个都不匹配,更没有分组匹配,将返回空数组

    fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxxbyc-axxbyc-axbyc-", -1)) //[["axxxbyc" "xxx" "y"] ["axxbyc" "xx" "y"] ["axbyc" "x" "y"]]
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxxbyc-axxbyc-axbyc-", 2)) //[["axxxbyc" "xxx" "y"] ["axxbyc" "xx" "y"]]
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxxbyc-axxbyc-axbyc-", 1)) //[["axxxbyc" "xxx" "y"]]
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-abzc-abzc-", -1)) //[["abzc" "" "z"] ["abzc" "" "z"]]
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-abzc-abzc-", 1)) //[["abzc" "" "z"]]
    fmt.Printf("%q\n", re.FindAllStringSubmatch("-aczc-", -1)) //[],整个都不匹配,更没有分组匹配,将返回空数组
}

 

下面三个函数实现分组匹配查找索引:

func (*Regexp) FindSubmatchIndex

func (re *Regexp) FindSubmatchIndex(b []byte) []int

Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以通过起止位置对b做切片操作得到:b[loc[2*n]:loc[2*n+1]]。如果没有匹配到,会返回nil。

func (*Regexp) FindStringSubmatchIndex

func (re *Regexp) FindStringSubmatchIndex(s string) []int

Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以通过起止位置对b做切片操作得到:b[loc[2*n]:loc[2*n+1]]。如果没有匹配到,会返回nil。

func (*Regexp) FindReaderSubmatchIndex

func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int

Find返回一个保管正则表达式re在b中的最左侧的一个匹配结果以及(可能有的)分组匹配的结果的起止位置的切片。匹配结果和分组匹配结果可以在输入流r的字节偏移量loc[0]到loc[1]-1(包括二者)位置找到。如果没有匹配到,会返回nil。

举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b(y|z)c")
    fmt.Println(re.FindSubmatchIndex([]byte("-axxxbyc-"))) //[1 8 2 5 6 7],即整体匹配字符串"-axxxbyc-"的[1,8]切片,分组1匹配[2,5],分组2匹配[6,7]切片
    fmt.Println(re.FindSubmatchIndex([]byte("-abzc-"))) //[1 5 2 2 3 4]
    fmt.Println(re.FindSubmatchIndex([]byte("-aczc-"))) //[],整个都不匹配,更没有分组匹配,将返回空数组
    fmt.Println(re.FindStringSubmatchIndex("-axxxbyc-")) //[1 8 2 5 6 7]
    fmt.Println(re.FindStringSubmatchIndex("-abzc-")) //[1 5 2 2 3 4]
    fmt.Println(re.FindStringSubmatchIndex("-aczc-")) //[],整个都不匹配,更没有分组匹配,将返回空数组
}

下面两个函数和上面三个函数的区别在与能够使用第二个参数决定返回匹配的数量:

func (*Regexp) FindAllSubmatchIndex

func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int

Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的起止位置的切片(第一层表示第几个匹配结果,完整匹配和分组匹配的起止位置对在第二层)。如果没有匹配到,会返回nil。

func (*Regexp) FindAllStringSubmatchIndex

func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int

Find返回一个保管正则表达式re在b中的所有不重叠的匹配结果及其对应的(可能有的)分组匹配的结果的起止位置的切片(第一层表示第几个匹配结果,完整匹配和分组匹配的起止位置对在第二层)。如果没有匹配到,会返回nil。

 举例:
package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b(y|z)c")
    fmt.Println(re.FindAllSubmatchIndex([]byte("-axxxbyc-axxbyc-axbyc-"), -1)) //[[1 8 2 5 6 7] [9 15 10 12 13 14] [16 21 17 18 19 20]]
    fmt.Println(re.FindAllSubmatchIndex([]byte("-axxxbyc-axxbyc-axbyc-"), 2)) //[[1 8 2 5 6 7] [9 15 10 12 13 14]]
    fmt.Println(re.FindAllSubmatchIndex([]byte("-axxxbyc-axxbyc-axbyc-"), 1)) //[[1 8 2 5 6 7]]
    fmt.Println(re.FindAllSubmatchIndex([]byte("-abzc-abzc-"), -1)) //[[1 5 2 2 3 4] [6 10 7 7 8 9]]
    fmt.Println(re.FindAllSubmatchIndex([]byte("-abzc-abzc-"), 1)) //[[1 5 2 2 3 4]]
    fmt.Println(re.FindAllSubmatchIndex([]byte("-aczc-"), -1)) //[],整个都不匹配,更没有分组匹配,将返回空数组

    fmt.Println(re.FindAllStringSubmatchIndex("-axxxbyc-axxbyc-axbyc-", -1)) //[[1 8 2 5 6 7] [9 15 10 12 13 14] [16 21 17 18 19 20]]
    fmt.Println(re.FindAllStringSubmatchIndex("-axxxbyc-axxbyc-axbyc-", 2)) //[[1 8 2 5 6 7] [9 15 10 12 13 14]]
    fmt.Println(re.FindAllStringSubmatchIndex("-axxxbyc-axxbyc-axbyc-", 1)) //[[1 8 2 5 6 7]]
    fmt.Println(re.FindAllStringSubmatchIndex("-abzc-abzc-", -1)) //[[1 5 2 2 3 4] [6 10 7 7 8 9]]
    fmt.Println(re.FindAllStringSubmatchIndex("-abzc-abzc-", 1)) //[[1 5 2 2 3 4]]
    fmt.Println(re.FindAllStringSubmatchIndex("-aczc-", -1)) //[],整个都不匹配,更没有分组匹配,将返回空数组
}

 

2)替换操作-即前缀带有Replace的函数

 

 

 

func (*Regexp) ReplaceAllLiteral

func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte

ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。repl参数被直接使用,不会使用Expand进行扩展。

func (*Regexp) ReplaceAllLiteralString

func (re *Regexp) ReplaceAllLiteralString(src, repl string) string

ReplaceAllLiteralString返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。repl参数被直接使用,不会使用Expand进行扩展。

 举例:
package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b") //进行最左最长匹配
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "T"))
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "$1"))
    fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "${1}"))
}

返回:

userdeMBP:go-learning user$ go run test.go
-T-T-
-$1-$1-
-${1}-${1}-

 下面两个函数和上面的区别在与当使用$时,不会再将其当作一个简单的字符,而是进行规则替换。了解规则可去看下面的Expand函数

func (*Regexp) ReplaceAll

func (re *Regexp) ReplaceAll(src, repl []byte) []byte

ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。在替换时,repl中的\'$\'符号会按照Expand方法的规则进行解释和替换,例如$1会被替换为第一个分组匹配结果。

func (*Regexp) ReplaceAllString

func (re *Regexp) ReplaceAllString(src, repl string) string

ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。在替换时,repl中的\'$\'符号会按照Expand方法的规则进行解释和替换,例如$1会被替换为第一个分组匹配结果。

 举例:

package main 
import(
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("a(x*)b")
    fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) //-T-T-

    //这里$1表示的是每一个匹配的第一个分组匹配结果
    //这里第一个匹配的第一个分组匹配为空,即将匹配的ab换为空值;
    //第二个匹配的第一个分组匹配为xx,即将匹配的axxb换为xx
    fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) //--xx-
    fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}w"))//-w-xxw-

    //因为这个例子每个匹配的第二个分组匹配都为空,所以将所有匹配字符串都替换成了空值
    fmt.Println(re.ReplaceAllString("-ab-axxb-", "${2}"))//---
}

 

 

func (*Regexp) ReplaceAllFunc

func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte

ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果(设为matched)都替换为repl(matched)。repl返回的切片被直接使用,不会使用Expand进行扩展。

func (*Regexp) ReplaceAllStringFunc

func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string

ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果(设为matched)都替换为repl(matched)。repl返回的字符串被直接使用,不会使用Expand进行扩展。

 举例:

服务端为:

package main 
import(
    "fmt"
    "net/http"
    "log"
    "html/template"
)


func index(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "hello world") //将html写到w中,w中的内容将会输出到客户端中
}

func login(w http.ResponseWriter, r *http.Request){
    fmt.Println("method", r.Method) //获得请求的方法
    r.ParseForm()
    if r.Method == "GET"{
        html := `<html>
<HEAD>
<title></title>
</HEAD>
<body>


<form action="http://localhost:9090/login" method="post">
    username: <input type="text" name="username">
    password: <input type="text" name=" 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go标准库的学习-mime/multipart发布时间:2022-07-10
下一篇:
GO-学习之golang自动下载所有依赖包发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap