从无格式文本中提取多个值
Extract multiple values from unformated text
我的问题是如何从这个多行文本中提取Count:
、Temp:
、Total:
、Used:
后面的值。
Welcome, user [User CP] [Count: 1,014,747.1] [some] [Ohter: 0]
Temp: 14.231 Total: 10.0 TB Used: 964.57 GB On line: 2 0 Traffic Count: 1995
10 (0 New) 0
所以我可以获得这些值 1,014,747.1
、14.231
、10.0TB
、964.57GB
然后分配给一个 go 结构,比如
struct {
Count float64
Temp float64
Total string
Used string
}
我试过使用正则表达式,但它导致我需要用相同的文本写四次正则表达式和 运行 四次才能一一提取这些值。为什么我需要 运行 4 次很清楚,因为我写了 4 个 regxp 来提取 for 值。
var count = regexp.MustCompile(`(?m)(Count:\s*(\d+([\,]\d+)*([\.]\d+)))`)
var temp = regexp.MustCompile(`(?m)(Temp:\s*(\d+[\.]?\d*))`)
var total = regexp.MustCompile(`(?m)(Total:\s*(\d+\.?\d*\s\w\w))`)
var used = regexp.MustCompile(`(?m)(Used:\s*(\d+\.?\d*\s\w\w))`)
// run these regexp to get values
我试过使用一个正则表达式,但是匹配结果包含很多空元素我无法通过固定索引获取值。
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`(?m)(Count:\s*(\d+([\,]\d+)*([\.]\d+)))|(Temp:\s*(\d+[\.]?\d*))|(Total:\s*(\d+\.?\d*\s\w\w))|(Used:\s*(\d+\.?\d*\s\w\w))`)
var str = `Welcome, user [User CP] [Count: 1,014,747.1] [some] [Ohter: 0]
Temp: 14.231 Total: 10.0 TB Used: 964.57 GB On line: 2 0 Traffic Count: 1995
10 (0 New) 0`
for i, match := range re.FindAllStringSubmatch(str, -1) {
fmt.Println(match, "found at index", i)
}
}
结果是,结果中有一些不同数量的空元素,所以我无法通过固定索引获取值。
[Count: 1,014,747.1 Count: 1,014,747.1 1,014,747.1 ,747 .1 ] found at index 0
[Temp: 14.231 Temp: 14.231 14.231 ] found at index 1
[Total: 10.0 TB Total: 10.0 TB 10.0 TB ] found at index 2
[Used: 964.57 GB Used: 964.57 GB 964.57 GB] found at index 3
1,014,747.1
在索引 2,14.231
在索引 6,10.0 TB
在索引 8,964.57 GB
在索引 10。所以我无法通过使用固定索引。
在 https://regex101.com/r/jenOHn/3 更清楚的子组结果,匹配信息显示了问题。
那么有没有更优雅的方法来提取这些值呢?值的顺序可能会有所不同,文本之间可能会有一些额外的词(或遗漏一些词),因此无法按计数长度提取。
我考虑过使用有限状态机,但不知道如何实现,而且我也不确定这样做的正确方法。
看起来您在那里有大量您实际上并没有尝试捕获的捕获组,以及许多不必要的指定内容,以及缺少的 s
标志。我已经清理了表达式并且它有效:https://play.golang.org/p/D9WxFCYQ8s0
(?ms)Count:\s*([0-9,.]+).*Temp:\s*([0-9.]+).*Total:\s*([0-9.]+).*Used:\s*([0-9.]+)
我的问题是如何从这个多行文本中提取Count:
、Temp:
、Total:
、Used:
后面的值。
Welcome, user [User CP] [Count: 1,014,747.1] [some] [Ohter: 0]
Temp: 14.231 Total: 10.0 TB Used: 964.57 GB On line: 2 0 Traffic Count: 1995
10 (0 New) 0
所以我可以获得这些值 1,014,747.1
、14.231
、10.0TB
、964.57GB
然后分配给一个 go 结构,比如
struct {
Count float64
Temp float64
Total string
Used string
}
我试过使用正则表达式,但它导致我需要用相同的文本写四次正则表达式和 运行 四次才能一一提取这些值。为什么我需要 运行 4 次很清楚,因为我写了 4 个 regxp 来提取 for 值。
var count = regexp.MustCompile(`(?m)(Count:\s*(\d+([\,]\d+)*([\.]\d+)))`)
var temp = regexp.MustCompile(`(?m)(Temp:\s*(\d+[\.]?\d*))`)
var total = regexp.MustCompile(`(?m)(Total:\s*(\d+\.?\d*\s\w\w))`)
var used = regexp.MustCompile(`(?m)(Used:\s*(\d+\.?\d*\s\w\w))`)
// run these regexp to get values
我试过使用一个正则表达式,但是匹配结果包含很多空元素我无法通过固定索引获取值。
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`(?m)(Count:\s*(\d+([\,]\d+)*([\.]\d+)))|(Temp:\s*(\d+[\.]?\d*))|(Total:\s*(\d+\.?\d*\s\w\w))|(Used:\s*(\d+\.?\d*\s\w\w))`)
var str = `Welcome, user [User CP] [Count: 1,014,747.1] [some] [Ohter: 0]
Temp: 14.231 Total: 10.0 TB Used: 964.57 GB On line: 2 0 Traffic Count: 1995
10 (0 New) 0`
for i, match := range re.FindAllStringSubmatch(str, -1) {
fmt.Println(match, "found at index", i)
}
}
结果是,结果中有一些不同数量的空元素,所以我无法通过固定索引获取值。
[Count: 1,014,747.1 Count: 1,014,747.1 1,014,747.1 ,747 .1 ] found at index 0
[Temp: 14.231 Temp: 14.231 14.231 ] found at index 1
[Total: 10.0 TB Total: 10.0 TB 10.0 TB ] found at index 2
[Used: 964.57 GB Used: 964.57 GB 964.57 GB] found at index 3
1,014,747.1
在索引 2,14.231
在索引 6,10.0 TB
在索引 8,964.57 GB
在索引 10。所以我无法通过使用固定索引。
在 https://regex101.com/r/jenOHn/3 更清楚的子组结果,匹配信息显示了问题。
那么有没有更优雅的方法来提取这些值呢?值的顺序可能会有所不同,文本之间可能会有一些额外的词(或遗漏一些词),因此无法按计数长度提取。
我考虑过使用有限状态机,但不知道如何实现,而且我也不确定这样做的正确方法。
看起来您在那里有大量您实际上并没有尝试捕获的捕获组,以及许多不必要的指定内容,以及缺少的 s
标志。我已经清理了表达式并且它有效:https://play.golang.org/p/D9WxFCYQ8s0
(?ms)Count:\s*([0-9,.]+).*Temp:\s*([0-9.]+).*Total:\s*([0-9.]+).*Used:\s*([0-9.]+)