golang自然语言日期时间解析插件when的使用
golang自然语言日期时间解析插件when的使用
when
是一个自然语言日期/时间解析器,具有可插拔的规则和合并策略。
示例
以下是一些自然语言日期时间表达式的示例:
- tonight at 11:10 pm
- at Friday afternoon
- the deadline is next tuesday 14:00
- drop me a line next wednesday at 2:25 p.m
- it could be done at 11 am past tuesday
安装
要安装最新版本:
$ go get github.com/olebedev/when@latest
使用方法
基本用法
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/en"
)
func main() {
// 创建when解析器实例
w := when.New(nil)
// 添加英文规则和通用规则
w.Add(en.All...)
w.Add(common.All...)
// 要解析的文本
text := "drop me a line in next wednesday at 2:25 p.m"
// 解析文本,基于当前时间
r, err := w.Parse(text, time.Now())
if err != nil {
// 处理错误
}
if r == nil {
// 没有找到匹配的时间表达式
}
// 输出结果
fmt.Println(
"the time",
r.Time.String(),
"mentioned in",
text[r.Index:r.Index+len(r.Text)],
)
}
距离选项(Distance Option)
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/en"
"github.com/olebedev/when/rules"
)
func main() {
w := when.New(nil)
w.Add(en.All...)
w.Add(common.All...)
text := "February 23, 2019 | 1:46pm"
// 使用默认距离(5):
// February 23, 2019 | 1:46pm
// └───┬───┘
// distance: 9 (1:46pm将被忽略)
r, _ := w.Parse(text, time.Now())
fmt.Printf(r.Time.String())
// 输出: "2019-02-23 09:21:21.835182427 -0300 -03"
// 2019-02-23 (正确)
// 09:21:21 ("错误")
// 使用自定义距离(10):
w.SetOptions(&rules.Options{
Distance: 10,
MatchByOrder: true})
r, _ = w.Parse(text, time.Now())
fmt.Printf(r.Time.String())
// 输出: "2019-02-23 13:46:21.559521554 -0300 -03"
// 2019-02-23 (正确)
// 13:46:21 (正确)
}
工作原理
解析器会检查所有规则并提取一组匹配的规则,这些规则之间的距离小于或等于默认的options.Distance
(默认为5)。例如:
on next wednesday at 2:25 p.m.
└──────┬─────┘ └───┬───┘
weekday hour + minute
这样我们就得到了一个匹配规则簇 - 在字符串表示中的"next wednesday at 2:25 p.m."。
支持的语言
- EN - 英语
- RU - 俄语
- BR - 巴西葡萄牙语
- ZH - 中文
- NL - 荷兰语
项目状态
项目处于基本完成状态,已经在实际项目中使用。发现的问题会尽快修复。
许可证
Apache License 2.0
更多关于golang自然语言日期时间解析插件when的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang自然语言日期时间解析插件when的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 自然语言日期时间解析插件 when 的使用
when 是一个强大的自然语言日期时间解析库,可以将人类可读的日期时间字符串转换为 time.Time 对象。它支持多种语言和格式,非常适合处理用户输入的非结构化日期时间信息。
安装
go get -u github.com/olebedev/when
基本使用
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/en"
)
func main() {
// 创建 when 解析器
w := when.New(nil)
// 添加英文规则
w.Add(en.All...)
w.Add(common.All...)
// 解析自然语言日期时间
text := "Meet me at 3pm tomorrow"
r, err := w.Parse(text, time.Now())
if err != nil {
panic(err)
}
if r == nil {
fmt.Println("No date/time found in text")
return
}
fmt.Println("Matched text:", r.Text) // "3pm tomorrow"
fmt.Println("Parsed time:", r.Time) // 具体的 time.Time 对象
fmt.Println("Index in text:", r.Index) // 匹配文本的起始位置
fmt.Println("Source string:", text) // 原始字符串
}
高级用法
1. 自定义解析规则
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules"
)
// 自定义规则:解析 "next week" 为下周
type NextWeek struct{}
func (n *NextWeek) Apply(text string, t time.Time, opts rules.Options) *rules.MatchResult {
if text == "next week" {
return &rules.MatchResult{
Text: text,
Time: t.AddDate(0, 0, 7),
Index: 0,
}
}
return nil
}
func main() {
w := when.New(nil)
w.Add(&NextWeek{})
text := "Let's meet next week"
r, _ := w.Parse(text, time.Now())
fmt.Println("Parsed time:", r.Time) // 当前时间 + 7天
}
2. 多语言支持
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/ru" // 俄语规则
)
func main() {
w := when.New(nil)
w.Add(ru.All...)
w.Add(common.All...)
text := "встретимся через 2 дня" // 俄语"两天后见面"
r, _ := w.Parse(text, time.Now())
fmt.Println("Parsed time:", r.Time) // 当前时间 + 2天
}
3. 处理多个日期时间
package main
import (
"fmt"
"time"
"github.com/olebedev/when"
"github.com/olebedev/when/rules/common"
"github.com/olebedev/when/rules/en"
)
func main() {
w := when.New(nil)
w.Add(en.All...)
w.Add(common.All...)
text := "The event starts at 3pm tomorrow and ends at 5pm the day after"
base := time.Now()
// 查找所有匹配
var results []*rules.MatchResult
for {
r, err := w.Parse(text, base)
if err != nil || r == nil {
break
}
results = append(results, r)
text = text[r.Index+len(r.Text):] // 继续解析剩余文本
}
for i, r := range results {
fmt.Printf("Match %d: %q -> %v\n", i+1, r.Text, r.Time)
}
}
常见用例
1. 解析相对时间
text := "in 2 hours"
r, _ := w.Parse(text, time.Now())
fmt.Println(r.Time) // 当前时间 + 2小时
2. 解析绝对时间
text := "January 15, 2023 at 3pm"
r, _ := w.Parse(text, time.Now())
fmt.Println(r.Time) // 2023-01-15 15:00:00 +0000 UTC
3. 解析模糊时间
text := "next Monday"
r, _ := w.Parse(text, time.Now())
fmt.Println(r.Time) // 下周一 00:00:00
性能优化
对于需要频繁解析的场景,可以重用 when 实例:
var parser *when.Parser
func init() {
parser = when.New(nil)
parser.Add(en.All...)
parser.Add(common.All...)
}
func ParseDateTime(text string) (time.Time, error) {
r, err := parser.Parse(text, time.Now())
if err != nil || r == nil {
return time.Time{}, fmt.Errorf("could not parse date/time")
}
return r.Time, nil
}
注意事项
- 解析器对输入文本的大小写不敏感
- 对于模糊匹配,结果可能不是用户预期的,需要适当验证
- 复杂的日期时间表达式可能需要自定义规则
- 不同语言规则可能需要单独添加
when 库为处理自然语言日期时间提供了强大而灵活的工具,特别适合聊天机器人、日历应用等需要处理用户自由输入日期时间的场景。