鉴于我有一个表示类似HTML的属性的字符串,例如'attr="val" attr2="val2"'
,我想获取属性名称和值,但它变得复杂,因为值可以包含空格(因此不按空格分割是为了完成工作),并且它可以包含{{1} }和'
(请注意,字符串本身可以用"
或'
包围),最后可能会出现以反斜杠开头的引号,即"
或{{1 }}。我设法捕获了除最后一个之外的几乎所有内容 - 包含\'
或\"
的值。
Regexp我到目前为止:https://regex101.com/r/Z7q73R/1
我的目标是将字符串\"
转换为对象\'
。
答案 0 :(得分:1)
如果我们假设所有属性值都包含在双引号中,则名称由单词字符([a-zA-Z0-9_]
)组成,并且它们由空格字符分隔,至少...然后在正则表达式下按预期匹配:
(\w+)="([^\\"]*(?:\\.[^\\"]*)*)"
分解[^\\"]*(?:\\.[^\\"]*)*
块:
[^\\"]*
匹配除反斜杠和"
(?:
开始非捕获组
\\.
匹配转义字符[^\\"]*
匹配除反斜杠和"
)*
非捕获组结束,尽可能多地重复JS代码:
var str = `'attr="val" attr2="val2"'`;
var re = /(\w+)="([^\\"]*(?:\\.[^\\"]*)*)"/g;
while ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex)
re.lastIndex++;
console.log(m[1] + " => " + m[2])
}
答案 1 :(得分:0)
感谢@revo,我已经完成了正确的代码。我为了下降而在下面展示。
const regex = /(\w+)=(?:"([^\\"]*(?:\\.[^\\"]*)*)"|'([^\\']*(?:\\.[^\\']*)*)')/gm;
const str = `attr1="\\'val\\'\\"1\\"" attr2='val2a \\'hello\\' \\"yo\\" val2b'`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
console.log(m[1] + ' => ' + ( m[2] ? m[2] : m[3] ))
}
答案 2 :(得分:0)
你也可以这样做。
可读的正则表达式
( \w+ ) # (1), Attribute
\s*
= # =
\s*
( ["'] ) # (2), Value quote ', or "
( # (3 start), Value
[^"'\\]* # 0 to many not ",', or \ chars
(?: # --------
(?: # One of ...
\\ [\S\s] # Escape + anything
| # or,
(?! \2 | \\ ) # Not the value quote, nor escape
[\S\s]
) # -----------
[^"'\\]* # 0 to many not ",', or \ chars
)* # Do 0 to many times
) # (3 end)
\2 # Value quote ', or "
var str = "attr1=\"\\'val\\'\\\"1\\\"\" attr2='val2a \\'hello\\' \\\"yo\\\" val2b'\n" +
"attr3=\"val\" attr4=\"val\\\"2a\\\" val2b\"\n";
console.log( str );
var re = /(\w+)\s*=\s*(["'])([^"'\\]*(?:(?:\\[\S\s]|(?!\2|\\)[\S\s])[^"'\\]*)*)\2/g;
while ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex)
re.lastIndex++;
var atr = m[1];
var val = m[3];
// Remove escapes if needed
val = val.replace(/([^\\'"]|(?=\\["']))((?:\\\\)*)\\(["'])/g, "$1$2$3");
console.log( atr + " => " + val );
}