0

For update / problem solution scroll down or click here

Orig. question: I want to write a function in pure javascript which uses the Jquery-like selector with :eq(0) declarations, let's say e.g. to iterate trough a table like

$('tr:eq(8) > td:eq(13)').val();

For this I am trying to write a regex and I stuck here

var str = "I don't want +5+ and not 10 or [12] nor (120) but :eq(5) and :eq(120)";
var matches = str.match(/\:eq\(\d+(\d{1,2})\)?/g);
console.log('matches: '+matches);

which returns only matches: :eq(120) but not matches: :eq(5),:eq(120) as wanted. What can I do here ?

2
  • What about /\:eq\((\d{1,3})\)/g to match between 1 and 3 digits? Commented Mar 10, 2020 at 10:56
  • Yes this works too, more sophisticated regex as in Wills answer, but not needed here. Commented Mar 10, 2020 at 11:07

2 Answers 2

4

You can simplify your regex:

var str = "I don't want +5+ and not 10 or [12] nor (120) but :eq(5) and :eq(120)";
const matches = str.match(/:eq\(\d+\)/g);
console.log('matches: '+matches);

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

3 Comments

Soooo simple, I must have been blind ... 1+ and accepted answer, thanks
There're no needs to escape the colon.
@Toto you're right, one character less. the less the better :-)
0

UPDATE SUCCESS / RESULTS to share my toughts:

I have a table

<table>

    <tr>
        <td><span>1</span></td>
        <td><span id="span2">2</span></td>
        <td><span>3</span></td>
        <td><span>4</span></td>
    </tr>

    <tr>
        <td><span>5</span></td>
        <td><span>6</span></td>
        <td><span>7</span></td>
        <td><span>8</span></td>
    </tr>

</table>

and using the previous answers I wrote this small script, which is the beginning of a simple selector engine.

const ltrim = (haystack, needle) => {
    var regex = new RegExp('^'+needle);
    return haystack.replace(regex, '');
}

const rtrim = (haystack, needle) => {
    var regex = new RegExp(needle+'$');
    return haystack.replace(regex, '');
}

const $ = (s) => {
    var el = document;

    if (!s.match(/:eq/g)) {
        var cut_index = Math.max(s.lastIndexOf('>'),s.lastIndexOf(' '))+1;
        var last = s.substring(cut_index);
        if (/#/.test(last)) el = el.querySelector(s);
        else el = el.querySelectorAll(s);
    }
    else {
        var m = s.match(/:eq\(\d+\)/g);
        var p = s.split(/:eq\(\d+\)/g);
        for (i in p) {

            if (p[i] == '') i++;
            else {
                if (i == p.length-1) {
                    if (p[i].match(/#/)) el = el.querySelector(p[i]);
                    else el = el.querySelectorAll(p[i]);
                }
                else el = el.querySelectorAll(p[i])[m[i].match(/\d+/g)];
            }
        }
    }
    return el;
}

Now I can iterate trough the table using jquery-like selector syntax with

alert($('table tr td span#span2').innerHTML); // 2
alert($('table tr:eq(1) td:eq(1) span:eq(0)').innerHTML); // 6
alert($('table tr:eq(1) td:eq(2) span')[0].innerHTML); // 7

and I am happy for now. This expression, e.g.

$('table tr:eq(1) td span').forEach(elem => {elem.classList.add('yellow')});

uses regular JS syntax to highlight a complete row, or just one cell:

$('table tr:eq(1) td span:eq(2)').classList.add('yellow');

I'm not sure about the support of other jquery-like css selectors, will see in the future. In case of improvements further updates will be here.

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.