如何编写JS正则匹配Aveva Intouch关键字(排除注释与字符串)
正则修改方案
你之前的负向先行断言写法失效的核心原因是,这类断言只能判断当前位置往后的内容特征,无法回溯确认当前匹配的关键字是否已经处于被引号包裹的字符串内部,因此不能实现排除效果。
推荐采用「跳过排除段、捕获目标关键字」的正则逻辑,最终可用正则如下:/(?:{[^}]*}|(["'])(?:\\.|[^\\])*?\1)|(\b(?:as|eof|if|endif|then|dim)\b)/gmi
正则逻辑说明
- 开头的非捕获组
(?:{[^}]*}|(["'])(?:\\.|[^\\])*?\1)优先匹配所有不需要处理的内容:{[^}]*}:匹配{}包裹的注释块(["'])(?:\\.|[^\\])*?\1:匹配单/双引号包裹的字符串,同时支持转义引号场景(比如"str with \"quote\""可被正确识别为完整字符串)
- 后半段
(\b(?:as|eof|if|endif|then|dim)\b)为捕获组,仅当前面的排除内容都未匹配时才会命中,天然就过滤了注释和字符串内部的关键字
替换逻辑示例(JavaScript)
替换时只要判断关键字捕获组是否存在,存在就转大写,否则原样返回即可:
const formatIntouchCode = (rawCode) => { const keywordReg = /(?:{[^}]*}|(["'])(?:\\.|[^\\])*?\1)|(\b(?:as|eof|if|endif|then|dim)\b)/gmi return rawCode.replace(keywordReg, (match, _, keyword) => { return keyword ? keyword.toUpperCase() : match }) }
正则方案是否为最佳实践
不是最佳实践,仅适合简单场景快速实现:
- 正则很难覆盖所有边界异常,比如未闭合的注释、未闭合的字符串、嵌套语法等场景,很容易出现匹配错误
- 后续新增语法规则时,正则会变得极为臃肿,维护成本很高
如果要做生产级的格式化工具,更推荐基于VSCode的TextMate语法标记、或者自定义简易语法解析器来实现,直接识别token类型为关键字的内容进行转换,稳定性会高很多。如果你的需求仅覆盖常规业务场景,不需要处理极端异常代码,上述正则方案足够使用。
内容的提问来源于stack exchange,提问作者Vivil
相关产品推荐
相关产品推荐

