如何匹配${}插值中双引号外非}内容?适配Scheme Lisp解释器
问题解答
结论
简单场景下用单个正则表达式就能搞定;但如果${}里的Scheme代码有复杂嵌套(比如递归括号),就得写个小型解析器了。
优化后的正则
针对你要忽略双引号内的}、只认双引号外的}作为插值结束标记的需求,用这个正则就行:
const re = /(\$\{(?:[^"}\\]|\\.|"(?:[^"\\]|\\.)*")*\})/g;
正则工作逻辑
\$\{:匹配插值的起始标记${(?:...)为非捕获组,专门处理${}内部的合法内容:[^"}\\]:匹配普通字符,排除双引号、反斜杠、}\\.:匹配转义字符,比如\"、\}这类被转义的特殊符号"(?:[^"\\]|\\.)*":匹配完整的双引号字符串,支持字符串内包含转义双引号或其他转义字符
- 最终遇到未处于双引号/转义状态的
}时,结束当前插值的匹配
适用场景与局限性
- 适用场景:你给出的示例(比如
${(string-append "{" "hello" "}")})完全可以被正确匹配,用String.match(re)就能直接提取所有插值项;如果要用split,以该正则为分隔符,分割后筛选非分隔符部分即可。 - 局限性:如果
${}内的Scheme代码存在嵌套括号递归(比如${(if (> x 0) (string-append "a" "}") "b")}),正则无法处理这种递归结构,会出现匹配错误。此时必须编写小型解析器,通过跟踪括号层级、引号状态来准确识别插值的结束位置。
内容的提问来源于stack exchange,提问作者jcubic
相关产品推荐
相关产品推荐

