Lari13
Lari13

Reputation: 1870

JavaScript regular expression

I've some DOM node:

<p>[CROP:1049,160x608,557x897] [CROP:1055,264x501,513x461] Some text</p>

I've created regular expression:

var re = new RegExp("\[CROP:(\d+),(\d+)x(\d+),(\d+)x(\d+)\]", "ig");

But how can I get values from each (\d)?
As a result, I need to replace each [CROP:xxx] to <a> nodes like this:

<a href="#" class="myclass" data-id="1049" data-x1="160" data-x2="608" data-x3="557" data-x4="897">&nbsp;</a>

How can it be done? Thanks.

Upvotes: 1

Views: 518

Answers (5)

Brad Christie
Brad Christie

Reputation: 101604

var paragraphs = document.getElementsByTagName('p');
for (var p = 0; p < paragraphs.length; p++){
    var matches = paragraphs[p].innerHTML.match(/\[CROP:(\d+),(\d+)x(\d+),(\d+)x(\d+)\]/ig);
    console.log('matches: ' + matches.length + ' found. (' + matches.join(';') + ')');
    for (var m = 0; m < matches.length; m++){
        var data = /\[CROP:(\d+),(\d+)x(\d+),(\d+)x(\d+)\]/i.exec(matches[m]);
        console.log('data: ' + data + ' (' + data.length + ')');

        var a = document.createElement('a');
        a.href = '#';
        a.className = 'myclass';
        var attr = ['id','x1','x2','x3','x4'];
        for (var at = 0; at < attr.length; at++){
            a.setAttribute('data-'+attr[at],data[at+1]);
        }
        a.innerHTML = data.toString();

        document.getElementsByTagName('body')[0].appendChild(a);
    }
}

Something like that? Use <regex>.exec(<target>) to get the matches, then you can use setAttribute to append the data to the object.

Demo

Upvotes: 0

aorcsik
aorcsik

Reputation: 15552

You have to do this in 2 steps, I think there is no function to do this in one step:

  1. match all the [CROP:...] blocks
  2. match their inner parts

It would look like this:

function regex_func(pattern,text) {
    var i, max, sub = [],
        re = new RegExp(pattern, "ig"),
        match = text.match(re);
    if (match)
    {
        for (i=0, max=match.length; i<max; i++)
        {
            re = new RegExp(pattern, "i");
            sub[i] = re.exec(match[i]);    
        }
    }
    return sub;
}

var text = "[CROP:1049,160x608,557x897] [CROP:1055,264x501,513x461] Some text",
    pattern = "\\[CROP:(\\d+),(\\d+)x(\\d+),(\\d+)x(\\d+)\\]";
    matches = regex_func(pattern,text);

for (var i=0, max=matches.length; i<max; i++) {
    html = '<a href="#" class="myclass" data-id="'+matches[i][1]+'" data-x1="'+matches[i][2]+'" data-x2="'+matches[i][3]+'" data-x3="'+matches[i][4]+'" data-x4="'+matches[i][5]+'">'+matches[i][0]+'</a>';
    text = text.replace(matches[i][0],html);
}    

document.write(text);

You can text it here: http://jsfiddle.net/inti/fVQgp/5/

Edit: added the html string generation part, and the replace.

Edit 2: created a function to handle this matching problem. Used it in the actual problem.

Upvotes: 2

Colin
Colin

Reputation: 2021

The following will do what you are looking for

http://jsfiddle.net/Eb6b7/2/

I was unable to do this using a single RegEx, Here is the Javascript code from the link above:

var str = "[CROP:1,20x30,40x50] [CROP:9,8x00,400x500] [CROP:10,201x301,401x501] [CROP:100,21x31,41x51] some text";
var re1 = new RegExp(/\[CROP:(\d+),(\d+)x(\d+),(\d+)x(\d+)\]/ig);
var re2 = new RegExp(/\[CROP:(\d+),(\d+)x(\d+),(\d+)x(\d+)\]/);
var data1 = str.match(re1);
var data2 = str.match(re2);

// Example of RegEx 1
for(var i = 0; i < data1.length; i++)
    $('#parsed_content1').append("<div>" +data1[i] + "</div>");

// Example of RegEx 2
for(var i = 0; i < data2.length; i++)
    $('#parsed_content2').append("<div>" +data2[i] + "</div>");

// What you are looking for
for(var i = 0; i < data1.length; i++){
    var data3 = data1[i].match(re2);
    for(var j = 0; j < data3.length; j++)
    $('#overall').append("<div>" +data3[j] + "</div>");

}

Upvotes: 0

tomconte
tomconte

Reputation: 1020

You can do var mymatch = re.exec("mystring"). The resulting variable will hold the text matched by the capturing parentheses.

EDIT: sorry, mymatch[0] contains the matched string, mymatch[1] the text matched by the first set of parenthses, etc.

Upvotes: 0

pedz
pedz

Reputation: 2349

From the ECMA spec:

15.10.6.2 RegExp.prototype.exec(string) Performs a regular expression match of string against the regular expression and returns an Array object containing the results of the match, or null if string did not match.

e.g. match_data = re.exec(str)

Then match_data[1], ... will have each of the values within the parens.

Upvotes: 1

Related Questions