JavaScript中匹配Arduino setup函数体的正则表达式问题
提取Arduino代码中setup函数体的JavaScript正则解决方案
问题说明
给定Arduino代码:
#include "DigiKeyboard.h" void setup() { #start_shift_3 DigiKeyboard.sendKeyStroke(0); #end_shift_3 } void loop() { DigiKeyboard.delay(2000); }
需求是提取setup函数大括号内的内容,期望结果:
#start_shift_3 DigiKeyboard.sendKeyStroke(0); #end_shift_3
原正则表达式在测试网站有效,但JavaScript中无法正常工作,怀疑是单行模式标志s的兼容性问题。原JavaScript测试代码:
var string = ` #include "DigiKeyboard.h" void setup(){ #start_shift_3 DigiKeyboard.sendKeyStroke(0); #end_shift_3 } void loop() { DigiKeyboard.delay(2000); } `; const regex = new RegExp("[setup]+[(][)][{]\\n(.+?)\\n+\\s+[}]"); console.log(string.match(regex) == null);
修正方案
方案1:使用ES2018+ dotAll模式(s标志)
JavaScript在ES2018及之后支持s标志(dotAll模式),让.可以匹配换行符。同时修正原正则的错误写法:
var string = ` #include "DigiKeyboard.h" void setup(){ #start_shift_3 DigiKeyboard.sendKeyStroke(0); #end_shift_3 } void loop() { DigiKeyboard.delay(2000); } `; // 修正后的正则,使用dotAll模式 const regex = /void setup\(\)\s*\{\n([\s\S]+?)\n\s*\}/s; const matchResult = string.match(regex); if (matchResult) { console.log(matchResult[1]); // 输出目标内容 } else { console.log("未匹配到setup函数体"); }
方案2:兼容旧版JavaScript环境
如果需要兼容不支持s标志的环境,用[\s\S]代替.([\s\S]匹配所有空白和非空白字符,即任意字符):
var string = ` #include "DigiKeyboard.h" void setup(){ #start_shift_3 DigiKeyboard.sendKeyStroke(0); #end_shift_3 } void loop() { DigiKeyboard.delay(2000); } `; // 兼容旧环境的正则,无需s标志 const regex = /void setup\(\)\s*\{\n([\s\S]+?)\n\s*\}/; const matchResult = string.match(regex); if (matchResult) { console.log(matchResult[1]); }
原正则的错误点
[setup]+写法错误:它会匹配s/e/t/u任意字符的组合,而非setup完整单词,应直接写setup。- 未考虑函数定义的空白:比如
setup() {中括号和大括号间的空格,需用\s*匹配任意空白。 - 无参数函数的匹配冗余:原正则中匹配参数的部分多余,
setup()无参数,直接写\(\)即可。 - 换行符匹配问题:旧版JS中
.不匹配换行,需用[\s\S]或s标志解决。
内容的提问来源于stack exchange,提问作者borma425
相关产品推荐
相关产品推荐

