文字列を数値に変換する


Tags: 文字列, シーケンス

文字列を数値に変換する

整数の場合はparse-integerが使えます。その他の場合はread-from-string を使用します。

(parse-integer "1")                     ;=> 1
(read-from-string "1/10")               ;=> 1/10
(read-from-string "1.2")                ;=> 1.2
(read-from-string "#c(1 1)")            ;=> #C(1 1)

read-from-stringは整数の場合でも利用できます。

整数については基数を指定することもできます。

(parse-integer "11" :radix 2)           ;=> 3
(parse-integer "11" :radix 8)           ;=> 9
(parse-integer "11" :radix 10)          ;=> 11
(parse-integer "11" :radix 16)          ;=> 17

:junk-allowed引数の活用

:junk-allowed を指定すれば数値として認識されたものより先のゴミ文字を無視できます。 このとき、数値が読み取れないと nil を返します。

(defvar *data*
  '("174円" "103円" "190円" "121円" "139円" "157円" "192円" "197円" "110円" "129円"
    "105円" "131円" "139円" "123円" "179円" "195円" "110円" "122円" "140円" "151円"))


(mapcar (lambda (x) (parse-integer x :junk-allowed T))
        *data*)
;=>  (174 103 190 121 139 157 192 197 110 129 105 131 139 123 179 195 110 122 140
;     151)
(defvar *data2*
  '("単価189円" "単価134円" "単価114円" "単価125円" "単価199円" "単価123円" "単価107円"
    "単価162円" "単価177円" "単価122円" "単価172円" "単価121円" "単価131円" "単価197円"
    "単価108円" "単価152円" "単価102円" "単価197円" "単価168円" "単価102円"))


(mapcar (lambda (x) 
          (parse-integer x
                         :junk-allowed T
                         :start (position-if #'digit-char-p x)))
        *data2*)
;=>  (189 134 114 125 199 123 107 162 177 122 172 121 131 197 108 152 102 197 168
;     102)
(defvar *data3*
  '("十六進表記でFCという数" "十六進表記でDBという数" "十六進表記で81という数"
    "十六進表記で60という数" "十六進表記で2Bという数" "十六進表記で8という数"
    "十六進表記で1Dという数" "十六進表記で8Dという数" "十六進表記で6Cという数"
    "十六進表記で4Eという数" "十六進表記でF6という数" "十六進表記でF0という数" 
    "十六進表記で48という数" "十六進表記で14という数" "十六進表記で4Dという数"
    "十六進表記で30という数" "十六進表記でFBという数" "十六進表記でDCという数" 
    "十六進表記で73という数" "十六進表記でEという数"))


(mapcar (lambda (s) 
          (parse-integer s
                         :junk-allowed T
                         :start (position-if (lambda (c)
                                               (digit-char-p c 16.))
                                             s)
                         :radix 16.))
        *data3*)
;=>  (252 219 129 96 43 8 29 141 108 78 246 240 72 20 77 48 251 220 115 14)

必ず数値が欲しい場合は次のようにすれば良いでしょう。

(or (parse-integer "no integer" :junk-allowed t) 0)
;=> 0