本文介绍一种可靠、可读性强的正则方案,通过“匹配引号内完整字符串”与“匹配引号外非空白非特殊字符序列”的双路径逻辑,准确提取如 #include "folder with spaces/file.txt" 中的 include 和 "folder with spaces/file.txt"(不含引号),避免将引号内空格误切为多个token。
在处理类 C 预处理指令(如 #include、#define)的自定义代码解析时,一个常见难点是:既要按空格/制表符分割 token,又要保留双引号内含空格的完整路径或变量名(例如 "folder with spaces/file.txt" 应作为一个整体,而非拆成 folder、with、spaces/file.txt)。标准的 \S+ 或 [^"\s]+ 无法满足该需求——前者会把引号当普通字符截断,后者则完全忽略引号边界。
推荐使用以下正则表达式(JavaScript 兼容,需启用 g 标志):
(?<=")[^#"]+(?=")|[^# \r\n"]+
该模式采用 “优先匹配引号内内容,再匹配引号外有效标识符” 的策略,由两个分支通过 | 组合:
(?匹配被双引号包裹的非 # 非 " 内容
[^# \r\n"]+:匹配引号外的合法标识符
✅ 实际应用示例(JavaScript):
const code = `#include "folder/file.txt" #include "folder with spaces/file.txt" #include "$variable/file.txt" #define $foo joe #define $bar 34`; const regex = /(?<=")[^#"]+(?=")|[^# \r\n"]+/g; const tokens = code.match(regex) || []; console.log(tokens); // 输出: // [ // 'include', 'folder/file.txt', // 'include', 'folder with spaces/file.txt', // 'include', '$variable/file.txt', // 'define', '$foo', 'joe', // 'define', '$bar', '34' // ]
⚠️ 注意事项:

总结:该双分支正则以清晰的语义分离「引号内原子值」与「指令外标识符」,兼顾准确性与可维护性,是轻量级配置/脚本解析的理想选择。