diff --git a/packages/amis-ui/src/components/formula/Editor.tsx b/packages/amis-ui/src/components/formula/Editor.tsx index 7c8d549b9..312a5c64e 100644 --- a/packages/amis-ui/src/components/formula/Editor.tsx +++ b/packages/amis-ui/src/components/formula/Editor.tsx @@ -138,6 +138,24 @@ export class FormulaEditor extends React.Component< evalMode: true }; + static replaceStrByIndex( + str: string, + idx: number, + key: string, + replaceKey: string + ) { + const from = str.slice(0, idx); + const left = str.slice(idx); + return from + left.replace(key, replaceKey); + } + + static getRegExpByMode(evalMode: boolean, key: string) { + const reg = evalMode + ? `\\b${key}\\b` + : `\\$\\{[^\\{\\}]*\\b${key}\\b[^\\{\\}]*\\}`; + return new RegExp(reg); + } + static highlightValue( value: string, variables: Array, @@ -174,14 +192,18 @@ export class FormulaEditor extends React.Component< let from = 0; let idx = -1; while (~(idx = content.indexOf(v, from))) { - // 处理一下 \b 匹配不到的字符,比如 中文、[] 等 - const encodeHtml = html.replace(v, REPLACE_KEY); - const curNameEg = new RegExp(`\\b${REPLACE_KEY}\\b`, 'g'); // 避免变量识别冲突,比如:name、me 被识别成 na「me」 + const encodeHtml = FormulaEditor.replaceStrByIndex( + html, + idx, + v, + REPLACE_KEY + ); + const reg = FormulaEditor.getRegExpByMode(evalMode, REPLACE_KEY); // 如果匹配到则高亮,没有匹配到替换成原值 - if (curNameEg.test(encodeHtml)) { + if (reg.test(encodeHtml)) { html = encodeHtml.replace( - curNameEg, + REPLACE_KEY, `${varMap[v]}` ); } else { diff --git a/packages/amis-ui/src/components/formula/plugin.ts b/packages/amis-ui/src/components/formula/plugin.ts index 94a6681a7..2ec2d4376 100644 --- a/packages/amis-ui/src/components/formula/plugin.ts +++ b/packages/amis-ui/src/components/formula/plugin.ts @@ -4,7 +4,7 @@ import type CodeMirror from 'codemirror'; import {eachTree} from 'amis-core'; -import type {FormulaEditorProps, VariableItem} from './Editor'; +import {FormulaEditorProps, VariableItem, FormulaEditor} from './Editor'; export function editorFactory( dom: HTMLElement, @@ -179,6 +179,7 @@ export class FormulaPlugin { const vars = Object.keys(varMap).sort((a, b) => b.length - a.length); const editor = this.editor; const lines = editor.lineCount(); + const {evalMode = true} = this.getProps(); for (let line = 0; line < lines; line++) { const content = editor.getLine(line); @@ -205,10 +206,15 @@ export class FormulaPlugin { let from = 0; let idx = -1; while (~(idx = content.indexOf(v, from))) { - const encode = content.replace(v, REPLACE_KEY); - const curNameEg = new RegExp(`\\b${REPLACE_KEY}\\b`, 'g'); + const encode = FormulaEditor.replaceStrByIndex( + content, + idx, + v, + REPLACE_KEY + ); + const reg = FormulaEditor.getRegExpByMode(evalMode, REPLACE_KEY); - if (curNameEg.test(encode)) { + if (reg.test(encode)) { this.markText( { line: line,