RegExp捕获类似HTML的属性数据

时间:2018-05-20 20:48:15

标签: javascript regex

鉴于我有一个表示类似HTML的属性的字符串,例如'attr="val" attr2="val2"',我想获取属性名称和值,但它变得复杂,因为值可以包含空格(因此不按空格分割是为了完成工作),并且它可以包含{{1} }和'(请注意,字符串本身可以用"'包围),最后可能会出现以反斜杠开头的引号,即"或{{1 }}。我设法捕获了除最后一个之外的几乎所有内容 - 包含\'\"的值。

Regexp我到目前为止:https://regex101.com/r/Z7q73R/1
我的目标是将字符串\"转换为对象\'

3 个答案:

答案 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 );
}