明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 393|回复: 5

[经验] 多条件查找和多内容一一 替换插件

[复制链接]
发表于 前天 20:31 来自手机 | 显示全部楼层 |阅读模式
最近用AI写了一个lisp插件。支持多条件对应多内容一一替换(保留查找条件不变)


目前发现一个问题,就是输入条件内容和替换内容 对于输入长度有限制255字符(我想查找上千个内容,然后替换上千条)。
特放出代码看看有没有解决办法。

(defun c:ddth (/ *error* findList replaceList replacePairs selSet entData txtContent mode regex originalContent
                  dcl_id find_str replace_str last_find last_replace tmpdcl)
  ;; 错误处理函数
  (defun *error* (msg)
    (if (and regex (eq 'VLA-OBJECT (type regex)))
      (vlax-release-object regex)
    )
    (if tmpdcl (vl-file-delete tmpdcl))
    (if dcl_id (unload_dialog dcl_id))
    (if (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*"))
      (princ (strcat "\n错误: " msg))
    )
    (princ)
  )

  ;; ========== 增强型字符串分割函数 ==========
  (defun splitString (str delim / pos result token)
    (cond
      ((or (null str) (= str "")) '())  ; 处理空输入情况
      (T
        (setq result '())
        (while (setq pos (vl-string-search delim str))
          (setq token (substr str 1 pos))
          (if (/= token "")  ; 跳过空项
            (setq result (cons (vl-string-trim " " token) result))
          )
          (setq str (substr str (+ pos 1 (strlen delim))))
        )
        (if (/= str "")  ; 添加最后一段
          (setq result (cons (vl-string-trim " " str) result))
        )
        (reverse result)
      )
    )
  )

  ;; ========== 增强型字符串替换 ==========
  (defun vl-replace-all (text searchStr replaceStr / len newText pos)
    (setq len (strlen searchStr)
          newText ""
          pos 0)
    (while (<= (+ pos len) (strlen text))
      (if (and
            (= (substr text (1+ pos) len) searchStr)
            (or (= pos 0) (wcmatch (substr text pos 1) "[~0-9A-Za-Z]")) ; 前导边界
            (or (= (+ pos len) (strlen text))
                (wcmatch (substr text (+ pos len 1) 1) "[~0-9A-Za-Z]")) ; 后继边界
          )
        (setq newText (strcat newText searchStr " → " replaceStr) ; 显示查找和替换内容
              pos (+ pos len))
        (setq newText (strcat newText (substr text (1+ pos) 1))
              pos (1+ pos))
      )
    )
    (strcat newText (substr text (1+ pos)))
  )

  ;; ========== 正则表达式替换函数 ==========
  (defun regex-replace (text pattern replacement)
    (setq regex (vlax-create-object "vbscript.regexp"))
    (vlax-put-property regex 'Global 1)
    (vlax-put-property regex 'Pattern pattern)
    (setq result (vlax-invoke regex 'Replace text replacement))
    (vlax-release-object regex)
    result
  )
  ;; 主程序
  (vl-load-com)
  
  ;; 读取上次输入
  (setq last_find (vl-registry-read "HKEY_CURRENT_USER\\Software\\DDTH" "LastFind"))
  (setq last_replace (vl-registry-read "HKEY_CURRENT_USER\\Software\\DDTH" "LastReplace"))

  ;; 创建临时DCL文件
  (setq tmpdcl (vl-filename-mktemp "ddth.dcl"))
  (setq dclfile (open tmpdcl "w"))
  (write-line
"ddth_dialog : dialog {
  label = \"批量文本替换\";
  : row {
    : boxed_column {
      label = \"查找内容(逗号分隔)\";
      : edit_box {
        key = \"find\";
        width = 50;
        allow_accept = true;
      }
    }
    : boxed_column {
      label = \"替换内容(逗号分隔)\";
      : edit_box {
        key = \"replace\";
        width = 50;
        allow_accept = true;
      }
    }
  }
  spacer;
  : row {
    fixed_width = true;
    alignment = centered;
    : button {
      key = \"accept\";
      label = \"确定\";
      is_default = true;
    }
    : button {
      key = \"cancel\";
      label = \"取消\";
      is_cancel = true;
    }
  }
}" dclfile)
  (close dclfile)

  ;; 加载对话框
  (setq dcl_id (load_dialog tmpdcl))
  (if (not (new_dialog "ddth_dialog" dcl_id))
    (progn (alert "无法加载对话框!") (exit))
  )

  ;; 初始化对话框
  (set_tile "find" (if last_find last_find ""))
  (set_tile "replace" (if last_replace last_replace ""))

  ;; 设置动作
  (action_tile "accept" "(setq find_str (get_tile \"find\") replace_str (get_tile \"replace\")) (done_dialog 1)")
  (action_tile "cancel" "(done_dialog 0)")

  ;; 显示对话框
  (setq dcl_res (start_dialog))
  (unload_dialog dcl_id)
  (vl-file-delete tmpdcl)
  (setq tmpdcl nil)

  (if (= dcl_res 0)
    (exit)
    (progn
      ;; 保存输入到注册表
      (vl-registry-write "HKEY_CURRENT_USER\\Software\\DDTH" "LastFind" find_str)
      (vl-registry-write "HKEY_CURRENT_USER\\Software\\DDTH" "LastReplace" replace_str)

      ;; 处理输入内容
      (setq findList (splitString find_str ","))
      (setq replaceList (splitString replace_str ","))
      
      (if (/= (length findList) (length replaceList))
        (progn
          (alert "错误: 查找项与替换项数量不一致!")
          (exit)
        )
      )
    )
  )

  ;; 创建替换对集合
  (setq replacePairs (mapcar 'cons findList replaceList))
  
  ;; 对象选择
  (prompt "\n请选择要处理的TEXT/MTEXT对象: ")
  (setq selSet (ssget '((0 . "TEXT,MTEXT"))))
  
  ;; 替换执行
  (if selSet
    (progn
      (initget "Wcmatch Regex")
      (setq mode (cond ((getkword "\n选择匹配模式 [Wcmatch(精确)/Regex(正则)] <W>: ")) ("Wcmatch")))
      
      (setq i 0
            totalReplacements 0)
      (repeat (sslength selSet)
        (setq entData (entget (ssname selSet i))
              txtContent (cdr (assoc 1 entData))
              originalContent txtContent)
        
         ;; 根据模式选择替换算法
        (foreach pair replacePairs
          (setq txtContent
            (if (eq mode "Regex")
              (regex-replace txtContent
                            (strcat "\\b" (vl-string-translate "*?." "\\*\\?\\." (car pair)) "\\b")
                            (strcat (car pair) " → " (cdr pair))) ; 显示查找和替换内容
              (vl-replace-all txtContent (car pair) (cdr pair))
            )
          )
        )
        
        ;; 更新实体
        (if (not (equal txtContent originalContent))
          (progn
            (entmod (subst (cons 1 txtContent) (assoc 1 entData) entData))
            (setq totalReplacements (1+ totalReplacements))
          )
        )
        (setq i (1+ i))
      )
      (princ (strcat "\n处理了 " (itoa i) " 个对象,成功替换 " (itoa totalReplacements) " 处文本"))
    )
    (princ "\n未选择有效对象")
  )
  (princ)
)

(princ "\n文本批量替换命令已加载,输入 ddth 启动。")
回复

使用道具 举报

发表于 前天 20:42 | 显示全部楼层
字符串限制罢了,我告诉一个最简单的方法,换到C#.
不简单的方法是:写入一个文件内,再读取它,就可以破除字符串数量限制.
回复 支持 反对

使用道具 举报

发表于 前天 21:05 | 显示全部楼层
255个字符都够表达一段话了,这是要替换字符还是重写文章?
还上千条,一条255个字符就得至少25W字符,12W汉字,是用CAD写书呢?
回复 支持 反对

使用道具 举报

发表于 昨天 08:17 | 显示全部楼层
收下了,备用
回复 支持 反对

使用道具 举报

发表于 昨天 15:27 | 显示全部楼层
强,太强了,实在是太强了!!!
回复 支持 反对

使用道具 举报

发表于 昨天 16:36 来自手机 | 显示全部楼层
收藏备用,感谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-8 04:18 , Processed in 0.181958 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表