1

I just need to get all attributes and text from given string via RegExp, if it's possible with one line RegExp would be wonderful. I want to get each attr from string if it is in " or ' or standalone.

  • Attr: value = "1" or value = '1' or value="1" or value='1' or value=1 or value=""
  • Attr: readonly or disabled

I tried, this but not works for me.

var s = '<option value="1" data-foo="Foo" readonly>Value 1</option>', m
m = s.match(/<option ([^>]*)>(.*)<\/option>/)
console.log(m)
// gives ["<option value="1" data-...adonly>Value 1</option>", "value="1" data-foo="Foo" readonly", "Value 1"]

Thanks a lot.

7
  • I'm not sure what you need it for, but would it work for you to try a selector like document.querySelector("option[value='1'][data-foo='Foo'][readonly]").outerHTML? Commented Dec 14, 2012 at 8:15
  • I need, if str has any attr, get all attrs from str or null. Commented Dec 14, 2012 at 14:36
  • I guess I didnt get what your input & desired output is. Commented Dec 14, 2012 at 14:38
  • why not s.split(" ")? Just curious if it could work Commented Dec 14, 2012 at 14:39
  • No split, cos attrVal can contain space. Commented Dec 14, 2012 at 14:39

3 Answers 3

2

Why not just create the element?

var s = '<option value="1" data-foo="Foo" readonly>Value 1</option>'​​​​​;

var test_element = document.createElement('div');
test_element.innerHTML = s;

var element = test_element.childNodes[0];
​var attributes = element.attributes;

for (var i = 0; i < attributes.length; i++) {
    var attribute = attributes[i];

    console.log(attribute.name, '=>', attribute.value);
}​

Output:

value => 1
data-foo => Foo
readonly =>  

Demo: http://jsfiddle.net/mcRc4/

Sign up to request clarification or add additional context in comments.

5 Comments

I guess the OP wants to check if the attribute value is specified in quotes or without.
@techfoobar: I dunno, the question is a little vague. I though that OP was just looking to extract the attributes of an element from a string.
Looking at it again, i'm confused too. If all the OP wants is getting the values, regex parsing is definitely not required or advised.
It does not work in ie7, cos test_element.childNodes[0] is nodeType=3 (textNode) for it, but ff say nodeType=1
@qeremy: How about childNodes[1]?
0

The following regex i believe fetches what you want (well, looks ugly for sure but)

s.match(/<option\s*([^\s\=]*)\s*\=*\s*([^\s\=]*)*\s*([^\s\=]*)\s*\=*\s*([^\s\=]*)*\s*([^\s\=]*)\s*\=*\s*([^\s\=]*)*>(.*)<\/option>/);

For s = '<option value="1" data-foo="Foo" readonly>Value 1</option>', it returns:

[
  "<option value="1" data-foo="Foo" readonly>Value 1</option>", // s itlsef
  "value", // first attr
  ""1"", // value as written in s (with double quotes)
  "data-foo", // second attr
  ""Foo"", // value as written in s (with double quotes)
  "readonly", // third attr
  undefined, // no value specified for readonly, so undefined
  "Value 1" // the option text
]

1 Comment

Thank but this is not useful for it, cos option could have not attr or more than 3.
0

Actually I was needing this for handling "option" elements with a more simple way, more simple regexp. Cos of ie doesn't not append if use innerHTML = append content for select elements. Append operation is mentioned at links below, but does not work for option elements. And than I find a solution for this problem. If append content is option or options than use handleOptionElements, if not use asyncInnerHTML.

function append(el, child) {
    if (child.nodeType === 1 || child.nodeType === 3) {
        // Without clone, removes element if it is copied from document
        return el.appendChild(child.cloneNode(true));
    }

    content = trim(content);
    if (content.substring(0, 7) === "<option" && 
            content.substring(content.length - 7) === "option>") {
        handleOptionElements(content, el);
    } else {
        el.innerHTML = content;
    }

    return el;
}

http://james.padolsey.com/javascript/asynchronous-innerhtml/
Ways to increase performance when set big value to innerHTML

var re_standaloneAttributes = /^(select|disabl)ed$/i,
    re_optionSearch = /<option\s*([^>]*)>(.*?)<\/option>/gi,
    re_attributeSearch = /([^\s]*)=["'](.*?)["']|([\w\-]+)/g;

function handleOptionElements(content, targetElement) {
    var options = [], attributes = [],
         optionElement, optionElements = [], createOption;

    (""+ content).replace(re_optionSearch, function(src1, attr, text) {
        if (!src1) return;
        (""+ attr).replace(re_attributeSearch, function(src2, name, value) {
            if (!src2) return;
            name = name || src2;
            value = value || (value = re_standaloneAttributes.test(name) ? name : "");
            attributes.push({name: name, value: value});
        });
        options.push({text: text || "", attributes: attributes});
        // Reset attributes for each element
        attributes = [];
    });

    createOption = (function() {
        var option = document.createElement("option");
        return function() { return option.cloneNode(true) };
    })();

    forEach(options, function(option) {
        optionElement = createOption();
        // optionElement.text doesn't work on ie 7-8
        optionElement.textContent = optionElement.innerText = option.text;
        forEach(option.attributes, function(attribute) {
            optionElement.setAttribute(attribute.name, attribute.value);
        });

        if (targetElement !== undefined) {
            targetElement.appendChild(optionElement);
        } else {
            optionElements.push(optionElement);
        }
    });

    return optionElements;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.