Извлечение нескольких значений из неформатированного текста - PullRequest
0 голосов
/ 06 апреля 2020

Мой вопрос заключается в том, как извлечь значение, следующее за Count:, Temp:, Total:, Used: из этого многострочного текста в go.

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
}

Я пробовал с регулярным выражением, но в результате мне нужно написать четыре regxp и запустить четыре раза с тем же текстом, чтобы извлечь эти значения по одному. Почему мне нужно запускать 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

Я пытался использовать одно регулярное выражение, но результат совпадения содержит много элементов emtpy, которые я не могу получить значение по фиксированному индексу.

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, информация о совпадении показывает проблему.

Так есть ли более элегантный способ извлечь эти значения? Порядок значений может варьироваться, и между текстом может быть какое-то дополнительное слово (или пропущено какое-то слово), поэтому извлечение по длине счета невозможно.

Я думал об использовании конечного автомата, но не могу понять, как это реализовать, и я также не уверен, что это правильный способ.

1 Ответ

1 голос
/ 06 апреля 2020

Похоже, у вас есть куча групп захвата, которые вы на самом деле не пытаетесь захватить, и множество ненужных вещей, а также отсутствующий флаг s. Я убрал выражение, и оно работает: https://play.golang.org/p/D9WxFCYQ8s0

(?ms)Count:\s*([0-9,.]+).*Temp:\s*([0-9.]+).*Total:\s*([0-9.]+).*Used:\s*([0-9.]+)
...