@@ -484,9 +484,9 @@ TCVB 格式规范:
4844841. 单个替换操作(SINGLE-REPLACE):
485485## OPERATION:SINGLE-REPLACE
486486## BEFORE_ANCHOR
487- [代码块:前锚点内容,用来划定范围,避免混淆]
487+ [代码块:前锚点内容,用来划定范围,避免混淆, 注意这个不需要紧挨着被替换串 ]
488488## AFTER_ANCHOR
489- [代码块:后锚点内容,用来划定范围,避免混淆]
489+ [代码块:后锚点内容,用来划定范围,避免混淆, 注意这个不需要紧挨着被替换串 ]
490490## OLD_CONTENT
491491[代码块:被替换内容]
492492## NEW_CONTENT
@@ -495,7 +495,7 @@ TCVB 格式规范:
4954952. 全局替换操作(GLOBAL-REPLACE):
496496## OPERATION:GLOBAL-REPLACE
497497## OLD_CONTENT
498- [代码块:被替换内容 ]
498+ [代码块:被全局替换的内容 ]
499499## NEW_CONTENT
500500[代码块:新内容]
501501
@@ -511,11 +511,11 @@ TCVB 格式规范:
5115114. 删除操作(DELETE):
512512## OPERATION:DELETE
513513## BEFORE_ANCHOR
514- [代码块:被删内容前的锚点内容 ]
514+ [代码块:被删除行前的锚点内容 ]
515515## AFTER_ANCHOR
516- [代码块:被删内容后的锚点内容 ]
516+ [代码块:被删除行后的锚点内容 ]
517517## DELETE_CONTENT
518- [代码块:被删除内容 ]
518+ [代码块:被删除行的内容 ]
519519
5205205. 创建操作(CREATE):
521521## OPERATION:CREATE
@@ -582,36 +582,72 @@ export function mergeCvb(baseCvb: Cvb, tcvb: TCVB) : Cvb
582582 return rebuildCvb ( baseCvb , mapMergedFiles ) ;
583583}
584584
585- function applySingleReplace ( strContent : string , op : SingleReplaceOperation ) : string
586- {
587- const regPattern : RegExp = buildPattern ( op . m_strBeforeAnchor , op . m_strOldContent , op . m_strAfterAnchor ) ;
588- const strReplacement : string = op . m_strBeforeAnchor + op . m_strNewContent + op . m_strAfterAnchor ;
585+ function applySingleReplace ( strContent : string , op : SingleReplaceOperation ) : string {
586+ // 构建匹配模式:前锚点 + 中间内容1 + 旧内容 + 中间内容2 + 后锚点
587+ const regPattern = buildPattern ( op . m_strBeforeAnchor , op . m_strOldContent , op . m_strAfterAnchor ) ;
588+ // 替换为:前锚点 + 中间内容1 + 新内容 + 中间内容2 + 后锚点
589+ const strReplacement = op . m_strBeforeAnchor + '$1' + op . m_strNewContent + '$2' + op . m_strAfterAnchor ;
589590 return strContent . replace ( regPattern , strReplacement ) ;
590591}
591592
592593function applyGlobalReplace ( strContent : string , op : GlobalReplaceOperation ) : string
593594{
595+ if ( op . m_strOldContent === "" )
596+ {
597+ throw new Error ( `全局替换为空` ) ;
598+ }
599+
594600 const regPattern : RegExp = new RegExp ( escapeRegExp ( op . m_strOldContent ) , 'gs' ) ;
595601 return strContent . replace ( regPattern , op . m_strNewContent ) ;
596602}
597603
598- function applyInsert ( strContent : string , op : InsertOperation ) : string
604+ function applyInsert ( strContent : string , op : InsertOperation ) : string
599605{
600- const regPattern : RegExp = buildPattern ( op . m_strBeforeAnchor , "((?:[ \\t]*(?:\\r?\\n))*)" , op . m_strAfterAnchor ) ;
601- const strReplacement : string = op . m_strBeforeAnchor + op . m_strInsertContent + op . m_strAfterAnchor ;
602- return strContent . replace ( regPattern , strReplacement ) ;
606+ if ( op . m_strBeforeAnchor === "" || op . m_strAfterAnchor === "" )
607+ {
608+ throw new Error ( "插入操作的前锚点或后锚点为空" ) ;
609+ }
610+
611+ // 将前后锚点转义后使用
612+ const strBeforeRegex : string = escapeRegExp ( op . m_strBeforeAnchor ) ;
613+ const strAfterRegex : string = escapeRegExp ( op . m_strAfterAnchor ) ;
614+ // 中间部分直接作为正则片段,不做转义
615+ const strMiddlePattern : string = "((?:[ \\t]*(?:\\r?\\n))*)" ;
616+
617+ const regPattern : RegExp = new RegExp ( strBeforeRegex + strMiddlePattern + strAfterRegex , 'gs' ) ;
618+ const strReplacement : string = op . m_strBeforeAnchor + op . m_strInsertContent + op . m_strAfterAnchor ;
619+
620+ return strContent . replace ( regPattern , strReplacement ) ;
603621}
604622
605- function applyDelete ( strContent : string , op : DeleteOperation ) : string
623+ function applyDelete ( strContent : string , op : DeleteOperation ) : string
606624{
607- const regPattern : RegExp = buildPattern ( op . m_strBeforeAnchor , op . m_strDeleteContent , op . m_strAfterAnchor ) ;
608- return strContent . replace ( regPattern , op . m_strBeforeAnchor + op . m_strAfterAnchor ) ;
625+ if ( op . m_strBeforeAnchor === "" || op . m_strAfterAnchor === "" )
626+ {
627+ throw new Error ( "删除操作的前锚点或后锚点为空" ) ;
628+ }
629+ if ( op . m_strDeleteContent === "" )
630+ {
631+ throw new Error ( "删除操作的内容为空" ) ;
632+ }
633+
634+ const regPattern : RegExp = buildPattern ( op . m_strBeforeAnchor , op . m_strDeleteContent , op . m_strAfterAnchor ) ;
635+ // 使用捕获组 $1 和 $2 来保留匹配到的前后附加内容(不删除)
636+ const strReplacement : string = op . m_strBeforeAnchor + "$1" + "$2" + op . m_strAfterAnchor ;
637+
638+ return strContent . replace ( regPattern , strReplacement ) ;
609639}
610640
611641// 根据前锚点、内容、后锚点构建正则表达式(dotall 模式)
612- function buildPattern ( strBefore : string , strContent : string , strAfter : string ) : RegExp
613- {
614- return new RegExp ( escapeRegExp ( strBefore ) + escapeRegExp ( strContent ) + escapeRegExp ( strAfter ) , 'gs' ) ;
642+ function buildPattern ( strBefore : string , strContent : string , strAfter : string ) : RegExp {
643+ return new RegExp (
644+ escapeRegExp ( strBefore ) +
645+ '([\\s\\S]*?)' + // 捕获前锚点与旧内容之间的任意字符(非贪婪)
646+ escapeRegExp ( strContent ) +
647+ '([\\s\\S]*?)' + // 捕获旧内容与后锚点之间的任意字符(非贪婪)
648+ escapeRegExp ( strAfter ) ,
649+ 'gs' // 全局匹配且允许跨行
650+ ) ;
615651}
616652
617653function rebuildCvb ( baseCvb : Cvb , mapFiles : Map < string , string > ) : Cvb
0 commit comments