Submitted by admin on 2018, June 7, 10:42 AM
package main
import (
"fmt"
"regexp"
)
var reg *regexp.Regexp
var pattern string
var source string
func regexpMatch() {
// xy 匹配x y
// x|y 匹配x或者y 优先x
// source = "asdfdsxxxyyfergsfasfxyfa"
// pattern = `x|y|a`
//x* 匹配零个或者多个x,优先匹配多个
//x+ 匹配一个或者多个x,优先匹配多个
//x? 匹配零个或者一个x,优先匹配一个
//source = "xxxxewexxxasdfdsxxxyyfergsfasfxyfa"
//pattern = `x*`
// x{n,m} 匹配n个到m个x,优先匹配m个
// x{n,} 匹配n个到多个x,优先匹配更多
// x{n} 或者x{n}? 只匹配n个x
//source = "xxxxxxxewexxxasdfdsxxxyyfergsfasfxyfa"
//pattern = `x{4,}`
// x{n,m}? 匹配n个到m个x,优先匹配n个
// x{n,}? 匹配n个到多个x,优先匹配n个
// x*? 匹配零个或者多个x,优先匹配0个
// x+? 匹配一个或者多个x,优先匹配1个
// x?? 匹配零个或者一个x,优先匹配0个
//source = "xxxxxxxewexxxasdfdsxxxyyfergsfasfxyfa"
//pattern = `x??`
//[\d] 或者[^\D] 匹配数字
//[^\d]或者 [\D] 匹配非数字
//source = "xx435ff5237yy6346fergsfasfxyfa"
//pattern = `[\d]{3,}` //匹配3个或者更多个数字
//source = "xx435ffGUTEYgjk52RYPHFY37yy6346ferg6987sfasfxyfa"
//pattern = `[a-z]{3,}` //三个或者多个小写字母
//source = "xx435ffGUTEYgjk52RYPHFY37yy6346ferg6987sfasfxyfa"
//pattern = `[[:alpha:]]{5,}` //5个或者多个字母,相当于A-Za-z
//source = "xx435,./$%(*(_&jgshgs发个^$%ffG返回福hjh放假啊啥UTEYgjk52RYPHFY37yy6346ferg6987sfasfxyfa"
//pattern = `[\p{Han}]+` //匹配连续的汉字
//source = "13244820821HG74892109977HJA15200806084S11233240697hdgsfhah假发发货"
//pattern = `1[3|5|7|8|][\d]{9}` //匹配电话号码
//source = "132@12.comGKGk15@163.cn200806084S11233240697hdgsfhah假发发货"
//pattern = `\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*` //匹配电子邮箱
//匹配用户名或者密码 `^[a-zA-Z0-9_-]{4,16}$` 字母或者数字开头,区分大小写,最短4位最长16位
//匹配IP地址1 `^$(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
//匹配IP地址2
//pattern = `((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)`
//匹配日期 年-月-日 `(\d{4}|\d{2})-((1[0-2])|(0?[1-9]))-(([12][0-9])|(3[01])|(0?[1-9]))`
//匹配日期 月-日-年 `((1[0-2])|(0?[1-9]))/(([12][0-9])|(3[01])|(0?[1-9]))/(\d{4}|\d{2})`
//匹配时间 小时:分钟 24小时制 ` ((1|0?)[0-9]|2[0-3]):([0-5][0-9]) `
//匹配邮编 `[1-9][\d]5`
//匹配URL `[a-zA-z]+://[^\s]*`
reg = regexp.MustCompile(pattern)
fmt.Printf("%s", reg.FindAllString(source, -1))
}
func main() {
regexpMatch()
}
golang | 评论:0
| Trackbacks:0
| 阅读:252
Submitted by admin on 2018, June 6, 11:58 PM
- // 中国大陆手机号码正则匹配, 不是那么太精细
- // 只要是 13,14,15,18 开头的 11 位数字就认为是中国手机号
- chinaMobilePattern = `^1[3458][0-9]{9}$`
- // 用户昵称的正则匹配, 合法的字符有 0-9, A-Z, a-z, _, 汉字
- // 字符 '_' 只能出现在中间且不能重复, 如 "__"
- nicknamePattern = `^[a-z0-9A-Z\p{Han}]+(_[a-z0-9A-Z\p{Han}]+)*$`
- // 用户名的正则匹配, 合法的字符有 0-9, A-Z, a-z, _
- // 第一个字母不能为 _, 0-9
- // 最后一个字母不能为 _, 且 _ 不能连续
- namePattern = `^[a-zA-Z][a-z0-9A-Z]*(_[a-z0-9A-Z]+)*$`
- // 电子邮箱的正则匹配, 考虑到各个网站的 mail 要求不一样, 这里匹配比较宽松
- // 邮箱用户名可以包含 0-9, A-Z, a-z, -, _, .
- // 开头字母不能是 -, _, .
- // 结尾字母不能是 -, _, .
- // -, _, . 这三个连接字母任意两个不能连续, 如不能出现 --, __, .., -_, -., _.
- // 邮箱的域名可以包含 0-9, A-Z, a-z, -
- // 连接字符 - 只能出现在中间, 不能连续, 如不能 --
- // 支持多级域名, x@y.z, x@y.z.w, x@x.y.z.w.e
- mailPattern = `^[a-z0-9A-Z]+([\-_\.][a-z0-9A-Z]+)*@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)*\.)+[a-zA-Z]+$`
golang | 评论:0
| Trackbacks:0
| 阅读:408
Submitted by admin on 2018, June 5, 11:41 AM
package main
import (
"encoding/json"
"fmt"
"os"
)
type ConfigStruct struct {
Host string `json:"host"`
Port int `json:"port"`
AnalyticsFile string `json:"analytics_file"`
StaticFileVersion int `json:"static_file_version"`
StaticDir string `json:"static_dir"`
TemplatesDir string `json:"templates_dir"`
SerTcpSocketHost string `json:"serTcpSocketHost"`
SerTcpSocketPort int `json:"serTcpSocketPort"`
Fruits []string `json:"fruits"`
}
type Other struct {
SerTcpSocketHost string `json:"serTcpSocketHost"`
SerTcpSocketPort int `json:"serTcpSocketPort"`
Fruits []string `json:"fruits"`
}
func main() {
jsonStr := `{"host": "http://localhost:9090","port": 9090,"analytics_file": "","static_file_version": 1,"static_dir": "E:/Project/goTest/src/","templates_dir": "E:/Project/goTest/src/templates/","serTcpSocketHost": ":12340","serTcpSocketPort": 12340,"fruits": ["apple", "peach"]}`
//json str 转map
var dat map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &dat); err == nil {
fmt.Println("==============json str 转map=======================")
fmt.Println(dat)
fmt.Println(dat["host"])
}
//json str 转struct
var config ConfigStruct
if err := json.Unmarshal([]byte(jsonStr), &config); err == nil {
fmt.Println("================json str 转struct==")
fmt.Println(config)
fmt.Println(config.Host)
}
//json str 转struct(部份字段)
var part Other
if err := json.Unmarshal([]byte(jsonStr), &part); err == nil {
fmt.Println("================json str 转struct==")
fmt.Println(part)
fmt.Println(part.SerTcpSocketPort)
}
//struct 到json str
if b, err := json.Marshal(config); err == nil {
fmt.Println("================struct 到json str==")
fmt.Println(string(b))
}
//map 到json str
fmt.Println("================map 到json str=====================")
enc := json.NewEncoder(os.Stdout)
enc.Encode(dat)
//array 到 json str
arr := []string{"hello", "apple", "python", "golang", "base", "peach", "pear"}
lang, err := json.Marshal(arr)
if err == nil {
fmt.Println("================array 到 json str==")
fmt.Println(string(lang))
}
//json 到 []string
var wo []string
if err := json.Unmarshal(lang, &wo); err == nil {
fmt.Println("================json 到 []string==")
fmt.Println(wo)
}
}
golang | 评论:0
| Trackbacks:0
| 阅读:324
Submitted by admin on 2018, April 17, 6:06 PM
文件下载之断点续传(客户端与服务端的实现)
https://www.cnblogs.com/zhaopei/p/download.html
文件各种上传,离不开的表单
http://www.cnblogs.com/zhaopei/p/upload.html
Golang实现断点续传
https://www.cnblogs.com/7explore-share/p/8111720.html
阿里云上传文件
https://helpcdn.aliyun.com/document_detail/32147.html
Go语言实现文件断点续传功能—resumable file uploads
HTTP 断点续传(分块传输)
https://blog.csdn.net/liang19890820/article/details/53215087
HTTP Range 请求
HTTP Range请求允许服务器向客户端发送HTTP消息体的一部分数据。Partial Requests在使用比较大的网络媒体文件或者在下载文件时提供暂停和恢复功能时很有用。
这也是下载时实现HTTP断点续传的一个关键。
HTTP 206 (Partial Content)
如果服务器能返回HTTP 206请求,我们就知道它能够支持Range request.
# curl -I https://www.baidu.com/ -H "Range: bytes=0-"
下载续传,一般WEB服务器,如nginx,apache,iis已支付,只在客户端实现即可
上传续传,也叫分片上传,需要分别在服务端,客户端实现
服务端针对分片的处理,获取当前的分片,每个分片上传保存,然后将分片合并
---
一些思路
提供一个思路,上传前先往数据库插入一条数据。数据包含文件要存的路径、文件名(用GUID命名,防止同名文件冲突)、文件MD5(用来识别下次续传和秒传)、临时文件块存放路径、文件是否完整上传成功等信息。
然后如果我们断网后再传,首先获取文件MD5值,看数据库里面有没上传完成的文件,如果有就实现秒传。如果没有,看是不是有上传了部分的。如果有接着传,如果没有则重新传一个新的文件。
golang | 评论:0
| Trackbacks:0
| 阅读:317
Submitted by admin on 2018, February 25, 4:34 PM
go编译的时候默认会将代码和行号包含到gdb调试信息里,使用gdb还是可以看见源码,编译的时候加-ldflags "-s -w"
可以去掉调试信息。
golang | 评论:0
| Trackbacks:0
| 阅读:364
Submitted by admin on 2017, December 23, 2:36 AM
- fmt.Println(time.Now().Unix()) //获取当前秒
- fmt.Println(time.Now().UnixNano())//获取当前纳秒
- fmt.Println(time.Now().UnixNano()/1e6)//将纳秒转换为毫秒
- fmt.Println(time.Now().UnixNano()/1e9)//将纳秒转换为秒
- c := time.Unix(time.Now().UnixNano()/1e9,0) //将毫秒转换为 time 类型
- fmt.Println(c.String()) //输出当前英文时间戳格式
golang | 评论:0
| Trackbacks:0
| 阅读:315
Submitted by admin on 2017, December 4, 2:36 PM
如何判断字符是不是中文, 以及中文的标点?
找到中文如何判断了:
package main import ( "fmt" "regexp" ) func main() { str := "问" var hzRegexp = regexp.MustCompile("^[\u4e00-\u9fa5]$") fmt.Println(hzRegexp.MatchString(str)) }
中文标点未知。
-------------
http://unicode.org/Public/UNIDATA/Blocks.txt
标点,当然是常用的:
3000..303F; CJK Symbols and Punctuation
Unicode规范比较复杂,中文其实你那个没有包括Non BMP字符,要弄全难度还是比较大。
-----------
用[\p{Han}]+
匹配中文,中文标点不清楚,不过也不多,都写上吧!
----------
go里面好像有支持,无需正则
/*
判断字符串是否包含中文字符
*/
func IsChineseChar(str string) bool {
for _, r := range str {
if unicode.Is(unicode.Scripts["Han"], r) {
return true
}
}
return false
}
golang | 评论:0
| Trackbacks:0
| 阅读:434
Submitted by admin on 2017, December 3, 1:05 PM
在golang的项目中,若要频繁的用redis(或者其他类似的NoSQL)来存取数据,最好用redigo自带的池来管理连接。
不然的话,每当要操作redis时,建立连接,用完后再关闭,会导致大量的连接处于TIME_WAIT状态(redis连接本质上就是tcp)。
注:TIME_WAIT,也叫TCP半连接状态,会继续占用本地端口。
以下为redis连接池的golang实现:
import (
"github.com/garyburd/redigo/redis"
"github.com/astaxie/beego"
"time"
)
var (
// 定义常量
RedisClient *redis.Pool
REDIS_HOST string
REDIS_DB int
)
func init() {
// 从配置文件获取redis的ip以及db
REDIS_HOST = beego.AppConfig.String("redis.host")
REDIS_DB, _ = beego.AppConfig.Int("redis.db")
// 建立连接池
RedisClient = &redis.Pool{
// 从配置文件获取maxidle以及maxactive,取不到则用后面的默认值
MaxIdle: beego.AppConfig.DefaultInt("redis.maxidle", 1),
MaxActive: beego.AppConfig.DefaultInt("redis.maxactive", 10),
IdleTimeout: 180 * time.Second,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", REDIS_HOST)
if err != nil {
return nil, err
}
// 选择db
c.Do("SELECT", REDIS_DB)
return c, nil
},
}
}
其中,各参数的解释如下:
MaxIdle:最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态。
MaxActive:最大的激活连接数,表示同时最多有N个连接
IdleTimeout:最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭
Dial:建立连接
使用连接池时的代码:
// 从池里获取连接
rc := RedisClient.Get()
// 用完后将连接放回连接池
defer rc.Close()
以上就是连接池的用法了,很简单吧。
golang | 评论:0
| Trackbacks:0
| 阅读:340