- 积分
- 1128
- 明经币
- 个
- 注册时间
- 2024-9-10
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
最近用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 启动。")
|
|