Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用regexp逐个值同时读取两个文件_Regex_Go_Simultaneous - Fatal编程技术网

使用regexp逐个值同时读取两个文件

使用regexp逐个值同时读取两个文件,regex,go,simultaneous,Regex,Go,Simultaneous,将两个文本文件合并为一个的小帮助工具。 这些文件存储一个大的二维浮点值数组。以下是其中一些: File 1 -0,1296169 -0,1286087 -0,1276232 ... -0,1288124 -0,1278683 -0,1269373 ... -0,1280221 -0,1271375 -0,12626 ... ... File 2 -0,1181779 -0,1200798 -0,1219472 ... -0,1198357 -0,1216468 -0,1234369 ...

将两个文本文件合并为一个的小帮助工具。 这些文件存储一个大的二维浮点值数组。以下是其中一些:

File 1
-0,1296169 -0,1286087 -0,1276232 ...
-0,1288124 -0,1278683 -0,1269373 ...
-0,1280221 -0,1271375 -0,12626  ...
...

File 2
-0,1181779 -0,1200798 -0,1219472 ...
-0,1198357 -0,1216468 -0,1234369 ...
-0,1214746 -0,1232006 -0,1249159 ...
... 
both may have hunderds of rows and columns ...
数值也可以采用科学形式(等1.234e-003)。 我的目标是逐值同时读取两个文件并写入输出,同时将delimeter从逗号固定到点,并在此过程中从科学形式转换到标准形式

这个版本的程序只合并了预处理的文件(delimeter更改为point,以标准形式表示的值和“每行一个值”移动的值),但如果文件的值超过百万,则进行这些准备是不真实的

以下是我目前的情况:

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "regexp"
)

func main() {
    file_dB, err := os.Open("d:/dB.txt")
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }
    file_dL, err := os.Open("d:/dL.txt")
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }
    file_out, err := os.Create("d:/out.txt") // also rewrite existing !
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }

    dB := bufio.NewReader(file_dB)
    dL := bufio.NewReader(file_dL)

    err = nil
    i := 1

    for {
        line1, _, err := dB.ReadLine()
        if len(line1) > 0 && line1[len(line1)-1] == '\n' {
            line1 = line1[:len(line1)-1]
        }
        line2, _, err := dL.ReadLine()
        if len(line2) > 0 && line2[len(line2)-1] == '\n' {
            line2 = line2[:len(line2)-1]
        }
        if len(line1) == 0 || len(line2) == 0 || err == io.EOF {
            fmt.Println("Total lines done: ", i)
            break
        } else if err != nil {
            fmt.Printf("Error while reading files: %v\n", err)
            os.Exit(1)
        }
        i++
        str := string(line1) + ";" + string(line2) + "\n"
        if _, err := file_out.WriteString(str); err != nil {
            panic(err)
        }
    }
}
如何使用regexp使此程序逐值读取未显示的文件(第一个列表),并将其形成如下形式:

-0.129617;-0.118178
-0.128609;-0.120080
-0.127623;-0.121947
...
输入文件的格式始终相同: -小数点分隔符是逗号 -值后一个空格(即使最后一行) -换行符在行尾

以前使用的表达式,如
([-?])([0-9]{1})([,]{1})([0-9]{1,12})({1})
和记事本++替换函数,将一行值拆分为每行一个值(与新的变量组合使用的表达式,如
$1$2.$4\r\n\
),但如果出现“科学形式”值,则会造成混乱


那么,有没有办法一个值一个值地读取文件,而不必将行拆分成片/子字符串并对其进行处理呢?

类似这样的内容。请注意假设每行的值数相同的限制。要小心,如果这个假设是错误的,它会出错:)

主程序包
进口(
“布菲奥”
“fmt”
“操作系统”
“strconv”
“字符串”
)
func main(){
文件\u dB,err:=os.Open(“dB.txt”)
如果错误!=零{
fmt.Printf(“打开文件时出错:%v\n”,错误)
返回
}
延迟文件\u dB.Close()
文件_dL,err:=os.Open(“dL.txt”)
如果错误!=零{
fmt.Printf(“打开文件时出错:%v\n”,错误)
返回
}
延迟文件\u dL.Close()
file_out,err:=os.Create(“out.txt”)//也重写现有的!
如果错误!=零{
fmt.Printf(“打开文件时出错:%v\n”,错误)
返回
}
延迟文件输出。关闭()
dB:=bufio.NewReader(文件\u dB)
dL:=bufio.NewReader(文件\u-dL)
立法会:=0
为了{
信用证++
第1行,错误:=dB.ReadLine()
vals1:=strings.Split(字符串(第1行),“”)
如果错误!=零{
格式打印LN(信用证,错误)
返回
}
第2行,错误:=dL.ReadLine()
vals2:=strings.Split(字符串(第2行),“”)
如果错误!=零{
格式打印LN(信用证,错误)
返回
}
//限制:假设第1行和第2行每行具有相同数量的值
对于i:=范围1{
dot1:=strings.Replace(vals1[i],“,”,“,”,1)
v1,err:=strconv.ParseFloat(dot1,64)
如果错误!=零{
格式打印LN(信用证,错误)
持续
}
dot2:=字符串.Replace(vals2[i],“,”,“,”,1)
v2,err:=strconv.ParseFloat(dot2,64)
如果错误!=零{
格式打印LN(信用证,错误)
持续
}
_,err=fmt.Fprintf(文件输出,“%v;%v\n”,v1,v2)
如果错误!=零{
格式打印LN(信用证,错误)
返回
}
}
}
}
例如

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "io"
    "os"
    "strconv"
    "strings"
)

var comma, period = []byte{','}, []byte{'.'}

func readNext(r io.Reader) func() (float64, error) {
    s := bufio.NewScanner(r)
    var fields []string
    return func() (float64, error) {
        if len(fields) == 0 {
            err := io.EOF
            for s.Scan() {
                line := bytes.Replace(s.Bytes(), comma, period, -1)
                fields = strings.Fields(string(line))
                if len(fields) > 0 {
                    err = nil
                    break
                }
            }
            if err := s.Err(); err != nil {
                return 0, err
            }
            if err == io.EOF {
                return 0, err
            }
        }
        n, err := strconv.ParseFloat(fields[0], 64)
        fields = fields[1:]
        if err != nil {
            return 0, err
        }
        return n, nil
    }
}

func main() {
    in1Name := `in1.data`
    in2Name := `in2.data`
    outName := `out.data`
    in1, err := os.Open(in1Name)
    if err != nil {
        fmt.Fprint(os.Stderr, err)
        return
    }
    defer in1.Close()
    in2, err := os.Open(in2Name)
    if err != nil {
        fmt.Fprint(os.Stderr, err)
        return
    }
    defer in2.Close()
    out, err := os.Create(outName)
    if err != nil {
        fmt.Fprint(os.Stderr, err)
        return
    }
    defer out.Close()
    outw := bufio.NewWriter(out)
    defer outw.Flush()

    next1 := readNext(in1)
    next2 := readNext(in2)
    for {
        n1, err1 := next1()
        n2, err2 := next2()
        if err1 == io.EOF && err2 == io.EOF {
            break
        }
        if err1 != nil || err2 != nil {
            fmt.Fprint(os.Stderr, err1, err2)
            return
        }
        _, err := fmt.Fprintf(outw, "%g;%g\n", n1, n2)
        if err != nil {
            fmt.Fprint(os.Stderr, err)
            return
        }
    }
}
游乐场:

输出:

$ go run  data.go
$ cat in1.data
-0,1296169 -0,1286087 -0,1276232 
-0,1288124 -0,1278683 -0,1269373 
-0,1280221 -0,1271375 -0,12626  
$ cat in2.data
-0,1296169 -0,1286087 -0,1276232 
-0,1288124 -0,1278683 -0,1269373 
-0,1280221 -0,1271375 -0,12626  
$ cat out.data
-0.1296169;-0.1296169
-0.1286087;-0.1286087
-0.1276232;-0.1276232
-0.1288124;-0.1288124
-0.1278683;-0.1278683
-0.1269373;-0.1269373
-0.1280221;-0.1280221
-0.1271375;-0.1271375
-0.12626;-0.12626
$ 

谢谢你的帮助,从其他民族的观点来看,我找到了自己的解决方案

此工具的作用是什么?通常它将两个文本文件合并为一个

我在哪里使用过它?为“国家特定坐标系工具”创建“通用ASCII”文本文件。输入文本文件是从GIS应用程序导出网格文件的ASCII格式(预期值为弧度)。稍后,当使用精确的GPS/GNSS接收机时,该文件可用于修复局部坐标偏移

以下是我“开发”的内容:


如果您有任何建议-请随时留言

我不明白你展示的输出是如何产生的?输出中每行上的两个值是什么?它们是否与第一个和第二个文件中的值相对应?这是怎么做到的?“将行拆分成片/子字符串并处理它们”可能会更快…:)您能为每个文件显示2个精确输入(5行)和预期的精确输出吗。确保两个值都使用科学记数法。文件第一行的前三个值是
-01296169-01286087-01276232…
-01181779-01200798-01219472…
,应按照上一个列表所示进行修改,因此第一行由第一个文件的值组成,第二行由第二个文件的值组成(或第一行-来自这些文件的第一个值,第二行-第二个值…)。因此file1line1
val1val2val3…
和file2line1
val1val2val3…
出来了。txt:line1像
val1;val1
,line2
val2;val2
等等。来自@peterSO的版本更全面、更整洁。
package main

import (
    "bufio"
    "fmt"
    "os"
    "regexp"
    "strconv"
    "strings"
)

func main() {
    file_dB, err := os.Open("d:/dB.txt")
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }
    defer file_dB.Close()
    file_dL, err := os.Open("d:/dL.txt")
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }
    defer file_dL.Close()
    file_out, err := os.Create("d:/out.txt") // also rewrite existing !
    if err != nil {
        fmt.Printf("error opening file: %v\n", err)
        os.Exit(1)
    }
    defer file_out.Close()

    dB := bufio.NewReader(file_dB)
    dL := bufio.NewReader(file_dL)

    err = nil
    xcorn_float := 0.0
    ycorn_float := 0.0
    cellsize_float := 0.0
    ncols := regexp.MustCompile("[0-9]+")
    nrows := regexp.MustCompile("[0-9]+")
    xcorn := regexp.MustCompile("[0-9]*,[0-9]*")
    ycorn := regexp.MustCompile("[0-9]*,[0-9]*")
    cellsize := regexp.MustCompile("[0-9]*,[0-9]*")
    nodataval := regexp.MustCompile("-?d+")
    tmp := 0.0

    // n cols --------------------
    ncols_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    ncols_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if ncols.FindString(ncols_dB) != ncols.FindString(ncols_dL) {
        panic(err)
    }
    ncols_dB = ncols.FindString(ncols_dB)
    // n rows --------------------
    nrows_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    nrows_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if nrows.FindString(nrows_dB) != nrows.FindString(nrows_dL) {
        panic(err)
    }
    nrows_dB = nrows.FindString(nrows_dB)
    // X --------------------
    xcorn_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    xcorn_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if xcorn.FindString(xcorn_dB) != xcorn.FindString(xcorn_dL) {
        panic(err)
    }
    xcorn_float, err = strconv.ParseFloat(strings.Replace(cellsize.FindString(xcorn_dB), ",", ".", 1), 8)
    xcorn_float *= 3600.0
    // Y --------------------
    ycorn_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    ycorn_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if ycorn.FindString(ycorn_dB) != ycorn.FindString(ycorn_dL) {
        panic(err)
    }
    ycorn_float, err = strconv.ParseFloat(strings.Replace(cellsize.FindString(ycorn_dB), ",", ".", 1), 8)
    ycorn_float *= 3600.0
    // cell size --------------------
    cellsize_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    cellsize_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if cellsize.FindString(cellsize_dB) != cellsize.FindString(cellsize_dL) {
        panic(err)
    }
    cellsize_float, err = strconv.ParseFloat(strings.Replace(cellsize.FindString(cellsize_dB), ",", ".", 1), 8)
    cellsize_float *= 3600.0
    // nodata value --------------------
    nodataval_dB, err := dB.ReadString('\n')
    if err != nil {
        panic(err)
    }
    nodataval_dL, err := dL.ReadString('\n')
    if err != nil {
        panic(err)
    }
    if nodataval.FindString(nodataval_dB) != nodataval.FindString(nodataval_dL) {
        panic(err)
    }
    nodataval_dB = nodataval.FindString(nodataval_dB)
    fmt.Print(nodataval_dB)
    //making header
    if _, err := file_out.WriteString("name\n3;0;2\n1;2;" + nrows_dB + ";" + ncols_dB + "\n" + strconv.FormatFloat(xcorn_float, 'f', -1, 32) + ";" + strconv.FormatFloat(ycorn_float, 'f', -1, 32) + ";" + strconv.FormatFloat(cellsize_float, 'f', -1, 32) + ";" + strconv.FormatFloat(cellsize_float, 'f', -1, 32) + "\n1\n"); err != nil {
        panic(err)
    }
    // valuses --------------------
    for {
        line1, err := dB.ReadString(' ')
        if err != nil {
            break
        }
        if tmp, err = strconv.ParseFloat(strings.TrimSpace(strings.Replace(line1, ",", ".", 1)), 64); err == nil {
            line1 = strconv.FormatFloat(tmp, 'f', 8, 64)
        }
        line2, err := dL.ReadString(' ')
        if err != nil {
            break
        }
        if tmp, err = strconv.ParseFloat(strings.TrimSpace(strings.Replace(line2, ",", ".", 1)), 64); err == nil {
            line2 = strconv.FormatFloat(tmp, 'f', 8, 64)
        }
        if err != nil {
            panic(err)
        }
        str := string(line1) + ";" + string(line2) + "\n"
        if _, err := file_out.WriteString(str); err != nil {
            panic(err)
        }
    }
}