freedom_ice 发表于 2022-11-8 15:52:04

(求助)字符串按数字分割输出表

请教,有任意字符串如

( setq str "CD61JY78K--45-A99SE" )拟返回
( CD 61 JY 78 K-- 45 -A 99 SE )已找到如下函数,可以去掉非数字字符,仅输入数字
( read ( strcat "("
                   ( vl-list->string ( mapcar '( lambda ( x ) ( if ( <= 48 x 57 ) x 32 ) )
                                             ( vl-string->list str )
                                     )
                   )
                  ")"
         )   
)是否可在此函数基础上修改,或者有什么别的好办法。我只能想到比较笨的办法,字符串转为字符表,用双指针挨个判断。

xiang19751218 发表于 2022-11-8 15:52:05

;(xd::string:regexps "\\-*+\\-*|\\d+" "CD61JY78K--45-A99SE" "")->("CD" "61" "JY" "78" "K--" "45" "-A" "99" "SE")
(defun XD::String:RegExpS (pat str key / end keys matches x)
(if (not *xxvbsexp)
    (setq *xxvbsexp (vlax-get-or-create-object "VBScript.RegExp"))
)
(vlax-put *xxvbsexp 'Pattern pat)
(if (not key)
    (setq key "")
)
(setq key (strcase key))
(setq keys '(("I" "IgnoreCase") ("G" "Global")
         ("M" "Multiline")
      )
)
(mapcar
    '(lambda (x)
       (if (wcmatch key (strcat "*" (car x) "*"))
         (vlax-put *xxvbsexp (read (cadr x)) 0)
         (vlax-put *xxvbsexp (read (cadr x)) -1)
       )
   )
    keys
)
(setq matches (vlax-invoke *xxvbsexp 'Execute str))
(vlax-for x matches (setq end (cons (vla-get-value x) end)))
(reverse end)
)

菜卷鱼 发表于 2022-11-8 16:24:46

你去学一下正则

x_s_s_1 发表于 2022-11-8 16:37:34

试试
;;;=============================================
;;;      通用函数 将字符串分解成表
;;;参数:Str------字符串
;;;      dot------考虑小数t是nil否
;;;      oi-------t返回ascii表,nil字符串表
;;;返回值 ascii表组成的表
;;;备注:此函数针对含特殊字符串的
(defun xty-str->list (str dot oi / tmp tmp1 tmp2 tmp3 a lst lst1 lst2)
(defun tmp (/ a)
    (setq a   (car lst)
    lst (cdr lst)
    )
    a
    )
(defun tmp1 (str / lst a b lst1)
    (setq lst (vl-string->list str))
    (while lst
      (setq a (tmp))
      (if (< a 129)
(setq lst1 (cons (list a) lst1))
(setq b   (tmp)
      lst1 (cons (list a b) lst1)
      )
)
      )
    (reverse lst1)
    )
(defun tmp2 (lst / typi typa a b c d e lst1 lsttmp)
    (defun typi (a) (and (< 47 a) (< a 58)))
    (defun typa(a)
      (or (and (< 64 a) (< a 91)) (and (< 96 a) (< a 123)))
      )
    (setq lsttmp lst
    a   (car (tmp))
    b   (car (tmp))
    c   (car (tmp))
    d   (car (tmp))
    e   (car (tmp))
    )
    (cond
      ((and (= 37 a) (= 37 b) (typi c) (typi d) (typi e))
       (setq lst1   (list a b c d e)
       lsttmp (cdr (cddddr lsttmp))
       )
       ) ;_符合%%###
      ((or (and e (= 37 a) (= 37 b) (typi c) (typi d) (null (typi e)))
   (and (= 37 a) (= 37 b) (typi c) (typi d) (null e))
   )
       (setq lst1   (list a b c d)
       lsttmp (cddddr lsttmp)
       )
       ) ;_符合%%##
      ((and (= 37 a) (= 37 b) (or (typa c) (typi c)))
       (setq lst1   (list a b c)
       lsttmp (cdddr lsttmp)
       )
       )
      )
    (list lst1 lsttmp)
    )
(defun tmp3 (lst dot / typa a lst1 lst2)
    (ifdot ;_是否考虑小数点
      (defun typa (a) (and (< 45 a) (< a 58) (/= 47 a)))
      (defun typa (a) (and (< 47 a) (< a 58)))
      )
    (setq lst2 nil
    lst1 nil
    )
    (while (or lst lst2)
      (setq a (tmp))
      (if (typa (car a)) ;_是否数字
(setq lst2 (append a lst2)) ;_是,组lst2
(if lst2
    (setqlst1 (cons (reverse lst2) lst1)
    lst1 (if a
         (cons a lst1)
         lst1
         )
    lst2 nil
    )
    (setq lst1 (cons a lst1))
    )
)
      )
    (reverse lst1)
    )
(setq lst (tmp1 str))
(while lst
    (if(car (setq lst2 (tmp2 lst)))
      (setq lst1 (cons (car lst2) lst1)
      lst   (cadr lst2)
      )
      (setq a   (tmp)
      lst1 (cons a lst1)
      )
      )
    )
(setqlst (reverse lst1)
lst (tmp3 lst dot)
)
(if oi
    lst
    (mapcar 'vl-list->string lst)
    )
)
(defun tt (str / a lst)
(setqlst nil
a   ""
)
(foreach n (xty-str->list str nil nil)
    (if(= 'INT (type (read n)))
      (setq lst(if (= a "")
      (cons n lst)
      (cons n (cons a lst))
      )
      a""
      )
      (setq a (strcat a n))
      )
    )
(setqlst (if(= a "")
      (reverse lst)
      (reverse (cons a lst))
      )
)
)

菜卷鱼 发表于 2022-11-8 17:02:36

本帖最后由 菜卷鱼 于 2022-11-8 17:05 编辑

负数要不要识别?
小数要不要识别?
下面是一段我已经废弃的代码,稍微拼了一下,目前来看跟你要的结果完全一致
如果你用得上,就没有枉费我当时的一番功夫
(setq str "CD61JY78K--45-A99SE" )
(splitnums str)
===>
("CD" "61" "JY" "78" "K--" "45" "-A" "99" "SE")

(defun splitnums (str / s a)
(setq s (spnum str))
(setq a (car s))
(while (wcmatch a "*#*")
    (setq s (append (spnum a) (cdr s)))
    (setq a (car s))
)
s
)
(defun spnum (str / spl pre stb num)
(if (wcmatch str "*#*")
    (progn
      (setq spl (split_str_last str))
      (setq pre(car spl)
      stb(cadr spl)
      )
      (setq spl (split_num_last pre))
      (setq pre(car spl)
      num(cadr spl)
      )
      (if (wcmatch pre "*#`.")
(progn
    (setq spl (split_last pre))
    (setqpre (car spl)
    num (strcat "." num)
    )
    (setq spl (split_num_last pre))
    (setqpre (car spl)
    num (strcat (cadr spl) num)
    )
)
      )
      (setq spl (split_num_real num))
      (setq pre(strcat pre (car spl))
      num(cadr spl)
      )
;;;;;以下句是为了保留负数
      ;|(if (wcmatch pre "*-")
(setq pre (car (split_last pre))
      num (strcat "-" num)
)
      )|;
      (list pre num stb)
    )
    (list str "" "")
)
)
;;;;分出尾部的字符串
(defun split_str_last (str / n l)
(setq n (strlen str))
(setq l n)
(while
    (and (> n 0)
   (wcmatch (substr str n 1) "~")
    )
   (setq n (1- n))
)
(cond
    ((= n l) (list str ""))
    ((< 1 n l) (list (substr str 1 n) (substr str (1+ n))))
    ((<= n 1) (list "" str))
)
)
;;;;分出尾部的数字
(defun split_num_last (str / n l)
(setq n (strlen str))
(setq l n)
(while
    (and (> n 0)
   (wcmatch (substr str n 1) "")
    )
   (setq n (1- n))
)
(cond
    ((= n l) (list str ""))
    ((<= 1 n l) (list (substr str 1 n) (substr str (1+ n))))
    ((< n 1) (list "" str))
)
)
(defun split_last (str / n)
(setq n (strlen str))
(if (> n 1)
    (list (substr str 1 (1- n)) (substr str n))
    (list "" str)
)
)
(defun split_num_real (num / n n2str pos)
(setq n (read num))
(setq n2str (vl-princ-to-string n))
(setq pos (vl-string-search n2str num))
(if (zerop pos)
    (list "" num)
    (list (substr num 1 pos) (substr num (1+ pos)))
)
)
(defun strnum-prc (str / pos)
(setq pos (vl-string-search "." str))
(if (null pos)
    0
    (- (strlen str) (1+ pos))
)
)


magicheno 发表于 2023-9-23 13:16:56

感谢大佬分享
页: [1]
查看完整版本: (求助)字符串按数字分割输出表