parse date

;;因为tokens被赋予了3个参数,目的是从一个字符串以不符合某些条件的字符为分隔符,获得分隔符之间的string对象的列表
(defun tokens (str test start)
  (let ((p1 (position-if test str :start start)))  ;;把p1设置为第一个符合test字符的位置
   (if p1
       (let ((p2 (position-if #'(lambda (c) 
                                  (not (funcall test c))) ;;返回不符合条件的字符的位置
                              str :start p1)))
         (cons (subseq str p1 p2) ;;
               (if p2 
                   (tokens str test p2) 
                   nil)))
       nil)))

;;字符是graphic小于127的字符,即ascii里面的字符就行。并且不等于空格
(defun constituent (c)
  (and (graphic-char-p c)
       (not (char= c #\  ))))

注意当你所得到的string对象的列表,如果该string调用parse-integer的话,必须确保里面自由数字和空格
(defun parse-date (str)
  (let ((toks (tokens str #'constituent 0)))
    (list (parse-integer (first toks))
          (parse-month   (second toks))
          (parse-integer (third toks)))))

(defconstant month-names
  #("jan" "feb" "mar" "apr" "may" "jun"
    "jul" "aug" "sep" "oct" "nov" "dec"))

(defun parse-month (str)
  (let ((p (position str month-names 
                     :test #'string-equal)))
    (if p
        (+ p 1)
        nil)))


(defun read-integer (str)
  (if (every #'digit-char-p str)         ;;;首先所有的char必须是一个数字形式
      (let ((accum 0))
        (dotimes (pos (length str))
          (setf accum (+ (* accum 10)
                         (digit-char-p (char str pos)))))
        accum)
      nil))


CL-USER> (tokens  "ar2012 aug 09f" #'constituent 0)    ;;意思是以空格或者大于127的字符为分隔符,然后返回这些分隔符之间string的list。
("ar2012" "aug" "09f")
CL-USER> (tokens "rr2010m10n02rr69" #'digit-char-p 0)  ;;基本上就是下面的read-integer的相同目的,只是read-integer将会返回一个这些分割出来的string对象连接起来的整数形式
("2010" "10" "02" "69")
CL-USER> (read-integer "rr2010m10n02rr69")
2010100269
CL-USER> (parse-date "2012 aug 03")                    ;;虽然刚开始的时候是graphic,并且仅仅用空格为分隔符,但是你像第一个第一个或者第3个string段,因为分段后需要进行parse-integer操作,故必须是数字,而中间的字符串要么是month-names 匹配,要么是数值。因为parse-month。
(2012 8 3)
下面一个程序实现提取一个字符串中的整数有多个注意点
1:digit-char-p意思是判断Returns true iff char is a digit,别误解为判断是否为char/digit.
2:(char str pos)返回一个字符,当你想用digit-char-p的值时,必须调用一下digit-char-p函数转化字符为相应的整数值。注意字符只能是(0-9).所以说现在digit-char-p共有两个用途
3:digit-char 把数字转化成char形式如9->#\9
4:关于dotimes的返回值,是它的第三个字符,默认为nil.所以你必须在let最后一个表达式为accum,否则let的值将是nil.
5:与上面read-integer的区别就是,上面的方法只限于string中的每个字符都是一个数字形式。
(defun read-integer (str)
  (let ((accum 0))
    (dotimes (pos (length str))
      (if (digit-char-p (char str pos))
	  (setf accum (+ (* accum 10) (digit-char-p (char str pos))))))
    accum))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值