You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JavaScript解析QML文件转JSON的正则替换问题求助

解决QML转JSON时的字符串引号包裹问题

我明白你在解析QML转JSON格式时遇到的正则难题了——要把那些没被双引号包裹的键和值都加上引号,同时避开已经在引号里的内容对吧?你的当前正则有两个明显的坑,咱们一步步来解决它。

先说说你现有正则的问题

  1. 引号导致匹配中断:你用的(?![^"]*")负向预查逻辑有问题——它会在遇到第一个双引号后,认为该行后续内容都在引号范围内,直接停止匹配,这就是为啥一行里有引号后其他单词都不被匹配的原因。
  2. 分组逻辑混乱:((\S\.\S)|\w+?)的分组设计太模糊,\S\.\S只能匹配单个字符+点+单个字符的情况(比如a.b),没法覆盖Layout.fillHeight这种多段的标识符,而且分组嵌套导致$1和$2的指向不明确,替换时自然拿不到正确内容。

给出解决方案

我们的核心思路是:跳过所有双引号包裹的内容,只在引号外的区域匹配需要加引号的键和值。下面是经过验证的正则和替换逻辑:

// 示例输入
const qmlInput = 'Layout.fillHeight: true height: 200 color: "transparent"';

// 执行替换
const jsonLikeOutput = qmlInput.replace(
  /(?<!")(\w+(?:\.\w+)*)(?=\s*:)|(?<=:\s*)(?!")(\w+|\d+)(?=\s*(?:\w|$))/g,
  '"$1$2"'
);

console.log(jsonLikeOutput);
// 输出:"Layout.fillHeight": "true" "height": "200" "color": "transparent"

正则逻辑拆解

这个正则分成两个分支,分别匹配键和未被引号包裹的值:

  1. 匹配键的分支:(?<!")(\w+(?:\.\w+)*)(?=\s*:)
    • (?<!"):确保当前位置前面没有双引号(排除已经被引号包裹的内容)
    • \w+(?:\.\w+)*:匹配QML的标识符,支持带点的多级命名(比如Layout.fillHeight)
    • (?=\s*:):确保后面跟着冒号(允许冒号前有空格)
  2. 匹配值的分支:(?<=:\s*)(?!")(\w+|\d+)(?=\s*(?:\w|$))
    • (?<=:\s*):确保当前位置前面是冒号加空格(匹配冒号后的内容)
    • (?!"):确保当前位置不是双引号的开头(排除已经被引号包裹的值)
    • \w+|\d+:匹配单词型值(比如true)或数字型值(比如200)
    • (?=\s*(?:\w|$)):确保后面是空格、下一个键的开头或者行尾(避免误匹配其他内容)
  3. 替换逻辑:"$1$2",因为每次匹配只会命中两个分支中的一个,所以$1或$2必有一个为空,拼接后就是正确的带双引号的内容。

边界情况适配

这个正则已经覆盖了常见的QML场景:

  • 支持带点的多级键名(比如Layout.fillWidth)
  • 支持数字值、布尔值(true/false)
  • 自动跳过已经被双引号包裹的内容
  • 支持键和值之间的任意空格

如果你的QML还有更复杂的场景(比如负数、带下划线的键名),这个正则也能直接适配,因为\w已经包含了下划线,负数的话可以把值的匹配部分改成-?\d+即可。

内容的提问来源于stack exchange,提问作者sgrumo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:31:31