从用户提交的文本中获取属性!正则表达式?

时间:2011-10-26 13:53:05

标签: javascript regex

我试图从Javascript中提交的文本中提取属性并将其更改为数组。

所以用户提交了这个:

<iframe src="http://www.stackoverflow.com/" width="123" height="123" frameborder="1"></iframe>

我会得到:

arr['src'] = http://www.stackoverflow.com/
arr['width'] = 123
arr['height'] = 123
arr['frameborder'] = 1

我认为只需要一个正则表达式,但任何帮助都会很棒!

5 个答案:

答案 0 :(得分:1)

我建议使用RegExp来解析用户输入的HTML,而不是创建DOM对象,因为在执行“简单”任务(例如获取属性值)时不希望加载外部内容(iframe, script, link, style, object, ...) HTML字符串。

使用与我的previous answer类似的(尽管类似的矛盾?)方法,我创建了一个匹配引用属性值的函数。两者都引用,因为非引用的属性是匹配的。

代码当前返回一个带有第一个标记属性的对象,但它很容易扩展以检索所有HTML元素(参见答案的底部)。

小提琴:http://jsfiddle.net/BP4nF/1/

// Example:
var htmlString = '<iframe src="http://www.stackoverflow.com/" width="123" height="123" frameborder="1" non-quoted=test></iframe>';
var arr = parseHTMLTag(htmlString);
//arr is the desired object. An easy method to verify:
alert(JSON.stringify(arr));

function parseHTMLTag(htmlString){
    var tagPattern = /<[a-z]\S*(?:[^<>"']*(?:"[^"]*"|'[^']*'))*?[^<>]*(?:>|(?=<))/i;
    var attPattern = /([-a-z0-9:._]+)\s*=(?:\s*(["'])((?:[^"']+|(?!\2).)*)\2|([^><\s]+))/ig;
    // 1 = attribute, 2 = quote, 3 = value, 4=non-quoted value (either 3 or 4)

    var tag = htmlString.match(tagPattern);
    var attributes = {};
    if(tag){ //If there's a tag match
        tag = tag[0]; //Match the whole tag
        var match;
        while((match = attPattern.exec(tag)) !== null){
            //match[1] = attribute, match[3] = value, match[4] = non-quoted value
            attributes[match[1]] = match[3] || match[4];
        }
    }
    return attributes;
}

示例的输出相当于:

var arr = {
    "src": "http://www.stackoverflow.com/",
    "width": "123",
    "height": "123",
    "frameborder": "1",
    "non-quoted": "test"
};

额外:修改功能以获得多个匹配(仅显示要更新的代码)

function parseHTMLTags(htmlString){
    var tagPattern = /<([a-z]\S*)(?:[^<>"']*(?:"[^"]*"|'[^']*'))*?[^<>]*(?:>|(?=<))/ig;
    // 1 = tag name
    var attPattern = /([-a-z0-9:._]+)\s*=(?:\s*(["'])((?:[^"']+|(?!\2).)*)\2|([^><\s]+))/ig;
    // 1 = attribute, 2 = quote, 3 = value, 4=non-quoted value (either 3 or 4)

    var htmlObject = [];
    var tag, match, attributes;
    while(tag = tagPattern.exec(htmlString)){
        attributes = {};
        while(match = attPattern.exec(tag)){
            attributes[match[1]] = match[3] || match[4];
        }
        htmlObject.push({
            tagName: tag[1],
            attributes: attributes
        });
    }
    return htmlObject; //Array of all HTML elements
}

答案 1 :(得分:0)

假设你正在做这个客户端,你最好不要使用RegExp,而是使用DOM:

var tmp = document.createElement("div");
tmp.innerHTML = userStr;

tmp = tmp.firstChild;
console.log(tmp.src);
console.log(tmp.width);
console.log(tmp.height);
console.log(tmp.frameBorder);

请确保不先将已创建的元素添加到文档中而不进行清理。您可能还需要循环创建的节点,直到到达element node

答案 2 :(得分:0)

假设他们总是会输入一个HTML元素,你可以解析它并从DOM中读取元素,就像这样(未经测试):

var getAttributes = function(str) {
  var a={}, div=document.createElement("div");
  div.innerHTML = str;
  var attrs=div.firstChild.attributes, len=attrs.length, i;
  for (i=0; i<len; i++) {
    a[attrs[i].nodeName] = attrs[i].nodeValue];
  }
  return a;
};

var x = getAttributes(inputStr);
x; // => {width:'123', height:123, src:'http://...', ...}

答案 3 :(得分:0)

使用纯JavaScript代替regexp:

抓住iframe元素:

var iframe = document.getElementsByTagName('iframe')[0];

然后使用以下方法访问其属性:

var arr = {
   src         : iframe.src,
   width       : iframe.width,
   height      : iframe.height,
   frameborder : iframe.frameborder
};

答案 4 :(得分:0)

如果可能,我会亲自与jQuery进行此操作。有了它,您可以创建一个DOM元素,而无需将其实际注入页面并产生潜在的安全隐患。

var userTxt = '<iframe src="http://www.stackoverflow.com/" width="123" height="123" frameborder="1"></iframe>';
var userInput = $(userTxt);
console.log(userInput.attr('src'));
console.log(userInput.attr('width'));
console.log(userInput.attr('height'));
console.log(userInput.attr('frameborder'));