对于像
{float: 'null', another: 'foo'}
这样的字符串,我想获取每组键/值对,以便各组输出 float
null
、another
和 foo
。
我当前的正则表达式是 /\{(?<set>(?<key>\w*)\s*\:\s*(?<value>.*)?\s?)*\}/g
它正确地获取键,但是从逗号开始的任何内容都会将其作为值接收。我使用命名组主要是为了清楚起见。无法弄清楚如何提取每个键/值对,特别是当有多个键/值对时。
感谢您的帮助
目前正在尝试
/\{(?<set>(?<key>\w*)\s*\:\s*(?<value>.*)?\s?)*\}/g
,但输出是:
组“设置”:
float: 'null', another: 'foo'
(正确)
组“关键”:
float
(正确)
组“值”:
'null', another: 'foo'
(不正确,我只想null
)
如果可能的话希望它捕获所有键/值对
编辑以获得更清晰的信息:
我的具体用例是解析 Markdown 并将其插入 Svelte 中的自定义组件,我想控制从图像上的 Markdown 语法收集道具的能力。根据我在网上收集的有关在图像上添加属性的信息,它应该看起来像这样:
![Alt Text]https://<fullurl>.jpg "This is hover text"){prop1: 'foo', prop2: 'bar', float: true}
正则表达式的原因是解析 Markdown 字符串。它不是 JSON,并且通过遵循 JSON 语义我并没有真正获得任何东西(
"
在关键上)
尝试一下这个长的 JavaScript 正则表达式:
/(?<key>\w*)\s*\:\s*(?<value>(?<quote>["'])(?:(?=(?<backslash>\\?))\k<backslash>.)*?\k<quote>|(?<number>[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)|(?<constant>true|false|null))/g
实际操作(整页查看,如果不是,则不全部可见):
const regexKeyValue = /(?<key>\w*)\s*\:\s*(?<value>(?<quote>["'])(?:(?=(?<backslash>\\?))\k<backslash>.)*?\k<quote>|(?<number>[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)|(?<constant>true|false|null))/g;
document.getElementById('search').addEventListener('click', function () {
const input = document.getElementById('input').value;
let match,
i = 1,
output = [];
while ((match = regexKeyValue.exec(input)) !== null) {
console.log(`Match n°${i} : ` + match[0]);
console.log('match.groups =', match.groups);
// If the value is starting with quotes, then unquoted it and
// also replace all the escape sequences (ex: "\\n" should become "\n").
let value = match.groups.value;
// If it's double quotes, let's use JSON.parse() as it will handle everything.
if (value.match(/^"/)) {
value = JSON.parse(value);
}
// If it's simple quotes, we can't use JSON.parse() so we have to trick it a bit.
else if (value.match(/^'/)) {
// 1) Remove the simple quotes around.
// 2) Replace all \' by '.
// 3) Escape all double quotes (" becomes \").
// We have to search for all backslashes to handle also an escaped backslash.
value = value
.replace(/^'|'$/g, '')
.replace(/\\(.)/g, function (fullMatch, afterBackslash) {
if (afterBackslash === "'") {
return "'";
} else {
return fullMatch;
}
}).
replace(/"/g, '\\"');
console.log(`"${value}"`);
// Now use JSON.parse();
value = JSON.parse(`"${value}"`);
}
// If it's a number or a constant, then convert the string to this real JS value.
if (typeof match.groups.number !== 'undefined' ||
typeof match.groups.constant !== 'undefined') {
value = eval(match.groups.value);
}
output.push(
`Match n°${i++} :\n` +
` Key : ${match.groups.key}\n` +
` Value : ${value}\n`
);
}
document.getElementById('output').innerText = output.join("\n");
document.getElementById('label').classList.remove('hidden');
});
textarea {
box-sizing: border-box;
width: 100%;
}
pre {
overflow-y: scroll;
}
.hidden {
display: none;
}
<textarea id="input" rows="10">{
float: 'null',
another: "foo",
age: 45,
type: '"simple" \' quote',
comment: "Hello,\nA backslash \\, a tab \t and a \"dummy\" word.\nOk?",
important: true,
weight: 69.7,
negative: -2.5
}</textarea>
<button id="search">Search for key-value pairs</button>
<p id="label" class="hidden">Matches:</p>
<pre><code id="output"></code></pre>
相同的正则表达式,带有注释,带有
x
标志
PCRE 提供:
/
(?<key>\w*)
\s*\:\s*
(?<value>
# A string value, single or double-quoted:
(?<quote>["'])
(?:(?=(?<backslash>\\?))\k<backslash>.)*?
\k<quote>
|
# Int and float numbers:
(?<number>[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)
|
# true, false and null (or other constants):
(?<constant>true | false | null)
)
/gx
或者更好的是,在 regex101 上,您将获得颜色和解释 右栏:https://regex101.com/r/bBPvUd/1
正如评论中提到的,
eval()
被认为是“邪恶的”或至少是不安全的。我已经忘记了具体原因,与跨端脚本有关。但是,如果在“安全”环境中使用,即。 e.对于您可以完全控制的输入的预处理,那么它可能仍然是可以接受的。
const md=`Some text and now the image:
![Alt Text]https://<fullurl>.jpg "This is hover text"){prop1: 'foo', prop2: 'bar', float: true}
and some more text.
A new paragraph any yet nother picture
![Alt Text2]https://<fullerURL>.jpg "This is another hover text"){prop1: 'fool', prop2: 'bart', float: false} and this is the end.`;
function unsafeParse(s){
return s.match(/\{[^}]+\}/g).map(t=>eval(`(${t})`));
}
// ouputs an array of all image property objects:
console.log(unsafeParse(md));
上述内容并不完全安全,因为包含“}”字符的属性值会导致问题......