Parsing all possible types of varying architectural dimension input

后端 未结 2 1847
梦谈多话
梦谈多话 2021-02-14 03:31

I am writing a library for our company\'s product that will take any kind of architectural dimension that our users are already familiar with as input for a function that conver

2条回答
  •  长发绾君心
    2021-02-14 04:04

    This may move your complexity from the branching logic to the regex logic:

    /(?(?\d+)(?\d{2})(?\d{2}))|((?[\d.]+)')?[\s-]*((?\d+)?[\s-]*((?\d+)\/(?\d+))?")?/
    

    If group special matches, you have the special syntax, and output is feet*12+inch+_sixt_/16, using ToDecimal on the groups. If not, you will have one or more of the groups feet, inch, numer and denom if the input is valid. Use ToDouble for feet and ToDecimal for the rest, and make sure to check for division by zero in the fraction.

    Proof-of-concept demonstration code (ruby):

    [
      ["12.5' "," 12 Feet and six inches "," 150.0"],
      ["11\"  "," 11 Inches "," 11.0"],
      ["3/16\" "," 3 sixteenths of an Inch "," 0.1875"],
      ["11' 11\" "," 11 Feet and 11 Inches "," 143.0"],
      ["11'11\" "," 11 Feet and 11 Inches "," 143.0"],
      ["12'-11\" "," 12 Feet and 11 Inches "," 155.0"],
      ["12' 11 3/16\" "," 12 Feet and 11 Inches and 3 sixteenths "," 155.1875"],
      ["12' 11-1/2\" "," 12 Feet and 11 Inches and 8 sixteenths "," 155.5"],
      ["12'   11     1/2\" "," 12 Feet and 11 Inches and 8 sixteenths "," 155.5"],
      ["121103 "," 12 Feet and 11 Inches and 3 sixteenths "," 155.1875"],
      ["", "empty string", "0"],
    ].each{|i,d,o|
      m = /(?(?\d+)(?\d{2})(?\d{2}))|((?[\d.]+)')?[\s-]*((?\d+)?[\s-]*((?\d+)\/(?\d+))?")?/.match(i)
      #puts "#{(1..8).map{|n|"%15s"%m[n].inspect}.join}"
      puts "#{"%20s"%i}   #{"%10s"%o}   #{m[:special] ? m[:feet].to_i*12+m[:inch].to_i+m[:sixt].to_i/16.0 : m[:feet].to_f*12+m[:inch].to_i+(m[:numer].to_i.to_f/(m[:denom]||1).to_i)} "
    }
    

    output:

                  12.5'         150.0   150.0 
                   11"           11.0   11.0 
                  3/16"        0.1875   0.1875 
                11' 11"         143.0   143.0 
                 11'11"         143.0   143.0 
                12'-11"         155.0   155.0 
           12' 11 3/16"      155.1875   155.1875 
            12' 11-1/2"         155.5   155.5 
      12'   11     1/2"         155.5   155.5 
                 121103      155.1875   155.1875 
                                    0   0.0 
    

    Please note that I haven't made any effort in testing other inputs than the valid ones you supplied. You may want to e.g. check for non-nil values in at least some of the capture groups, or maybe do validation as a separate step. This code was made with parsing in mind.

提交回复
热议问题