【问题标题】:Parse an array of strings解析字符串数组
【发布时间】:2020-11-12 17:01:35
【问题描述】:

我有一个字符串的一维数组( Array{String,1} ),它描述了一个浮点矩阵(见下文)。我需要解析这个矩阵。有什么巧妙的建议吗?

  • 朱莉娅 1.5
  • MacOS

是的,我确实是从文件中读到的。我不想使用 CSV 阅读整个内容,因为我想保留使用内存 I/O 读取整个文件的选项,我认为 CSV 没有。另外,我有一些复杂的行,包括字符串和数字,以及需要解析的字符串和字符串,这排除了 DelimitedFiles。这些列由两个空格分隔。

julia> lines[24+member_total:idx-1]
49-element Array{String,1}:
 "0.0000000E+00  0.0000000E+00  0.0000000E+00  1.3308000E+01"
 "0.0000000E+00  0.0000000E+00  1.9987500E-01  1.3308000E+01"
 "0.0000000E+00  0.0000000E+00  1.1998650E+00  1.3308000E+01"
 "0.0000000E+00  0.0000000E+00  2.1998550E+00  1.3308000E+01"
 "0.0000000E+00  0.0000000E+00  3.1998450E+00  1.3308000E+01"
 "0.0000000E+00  0.0000000E+00  4.1998350E+00  1.3308000E+01"
 ⋮
 "0.0000000E+00  0.0000000E+00  5.9699895E+01  1.4000000E-01"
 "0.0000000E+00  0.0000000E+00  6.0199890E+01  1.0100000E-01"
 "0.0000000E+00  0.0000000E+00  6.0699885E+01  6.2000000E-02"
 "0.0000000E+00  0.0000000E+00  6.1199880E+01  2.3000000E-02"
 "0.0000000E+00  0.0000000E+00  6.1500000E+01  0.0000000E+00"

【问题讨论】:

    标签: julia text-parsing


    【解决方案1】:

    我强烈反对重新发明轮子和使用定制的解析器,因为此类解决方案在生产中的实际稳健性。

    如果您的文件在单个 String 中,请使用:

    using DelimitedFiles
    readdlm(IOBuffer(strs))
    

    如果您的文件作为VectorStrings 使用

    cat(readdlm.(IOBuffer.(strsa))...,dims=1)
    

    最后,将内存映射与 CSV 一起使用没有冲突:

    using Mmap
    
    s = open("d.txt") # d.txt contains your lines
                      # if you want to read & wrtie use "w+" option
     
    m = Mmap.mmap(s, Vector{UInt8}) # memory mapping of your file
    
    readdlm(IOBuffer(m))
    
    

    同时,您始终可以将流设置为开头并读取数据而不管内存映射:

    seek(s,0)
    readdlm(s)
    seek(s,0) # reset the stream
    

    【讨论】:

    • 我也是。谢谢,这是一个非常巧妙的解决方案。我没有想到使用 IOBuffer 来输入 CSV 或 readdlm。对于像我这样的人,strs 是包含文件的字符串,strsa 是保存文件的字符串数组。 @PrzemyslawSzufel 我有几个问题要问你,因为很明显你是 julia 专家。您是否有一种巧妙的方法来解析具有数字和字母的字符串(我只想要数字)?例如:" 49 kp_total - Total number of key points (-) [must be at least 3]"
    • 你知道一种很好的方法来获取我读入的这些值(矩阵、字符串和标量),并将它们与其他字符串(标题、变量名和解释)一起写入文件,如我的上面的问题。我读入了一个字符串,其中包含我想要的标量值、var 名称和解释。我更改了标量值,我将把它写回文件。)?
    • 对于必须从Strings 中提取此类数据的问题 1,我会尝试正则表达式或更复杂的情况下对文本进行语义分析。对于问题 2,最自然的答案是使用 JSON 格式。
    【解决方案2】:
    strs = ["0.0000000E+00  0.0000000E+00  0.0000000E+00  1.3308000E+01",
            "0.0000000E+00  0.0000000E+00  1.9987500E-01  1.3308000E+01",
            "0.0000000E+00  0.0000000E+00  1.1998650E+00  1.3308000E+01"]
    
    mapreduce(vcat, strs) do s
        (parse.(Float64, split(s, "  ")))'
    end
    
    3×4 Array{Float64,2}:
     0.0  0.0  0.0       13.308
     0.0  0.0  0.199875  13.308
     0.0  0.0  1.19986   13.308
    

    【讨论】:

      【解决方案3】:

      我做了一个解决方法。不是最漂亮的东西,但它确实有效......

      function rmspaces(line)
          line = replace(line, "\t" => " ")
          # println("line: ", line)
          while occursin("  ", line)
              line = replace(line, "  "=>" ")
              # println("line: ", line)
          end
      
          return line
      end
      
      function readmatrix(lines, numcolumns::Int64; type=Float64)
          #Remove the spaces to one
          for i=1:length(lines)
              lines[i] = rmspaces(lines[i])
          end
      
          matrix = zeros(length(lines), numcolumns)
      
          for i=1:length(lines)
              idx = 1 # set the initial stop at the beginning
              spot = 1
              for j=1:length(lines[i])
                  if lines[i][j]==' ' && j>1 #Stops at spaces
                      number = parse(type,lines[i][idx:j]) #from the last stop to this one
                      idx = j #Set this stop in memory
                      matrix[i,spot] = number
                      spot += 1
                  end
              end
              if spot<numcolumns+1 #If there isn't a space after the last number,
                  #we need to attach the last number in every row. If the last number
                  #was appended, then the spot will be increased to be more than the number
                  #of columns.
                  number = parse(type, lines[i][idx:end])
                  matrix[i,spot] = number
              end
          end
          return matrix
      end
      

      【讨论】:

        猜你喜欢
        • 2020-06-21
        • 2023-04-07
        • 1970-01-01
        • 2015-05-12
        • 2017-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多