2

I'm a beginner in regex.

I've been trying on regex101 trying to figure out a way to capture the variable identifiers in declarations. Basically the x in var x = 1; but not x = x + 1.

I'm working with PrismJS to try to highlight my code and it doesn't support non-capturing (?:) and it captures every partial matches but it has an option to ignore the first brackets to imitate a "look-behind" function.

I test with the following text:

var a = 1,
    b=2,
    c = 3;
var d = 5;
var x, y = 3,
z;

var x = 1,
    z = 1.23E4, //comment
    w = +Infinity,
    u = NaN,
    t = 0x6F, //hexidecimal
    r = 0o37; //octadecimal

This far, I can only figure out a trick regex:

/(var *| *,\n* *)(\w+)(?= *=| *,| *;)/g
// not captured    ^   not captured
//             captured

The first brackets are ignored and not captured to imitate lookbehind. I can't make it work with var after | in the first brackets.

But of course, it will capture this as well which I don't want:

,
a =

Please help. There are so many limitations or maybe it's just me being too stupid, I can't construct a regex that works.

0

1 Answer 1

1

Okay, after a couple hours tinkering, here's a preliminary version!

The regex is /(var\s*|(?!^),\s*|(?!^),\s*\/\/ *.*?\n\s*)(\w+)/gm.

Explanation:

(
    var\s*                   // Matches "var" + whitespace (always a declaration)
  | (?!^),\s*                // Matches comma + whitespace
  | (?!^),\s*\/\/ *.*?\n\s*  // Matches comma + // comment + newline(s)
)
(\w+)                        // The identifier itself

By the way, this works in for loops, etc as well thanks to case 1 with var.

Case 3 is the funky one; it doesn't work for all cases but captures quite a lot of them. It looks for an inline comment following a comma (important) with whitespace around it.

Here's a demo below, where we highlight the variable names. Note that this doesn't capture the whole assignment, but you could add some optional stuff to highlight the whole thing or just the value as opposed to just the identifier.

function highlight (src) {
    var regex = /(var\s*|(?!^),\s*|(?!^),\s*\/\/ *.*?\n\s*)(\w+)/gm;
    return src.replace(regex, "$1<span class='hl'>$2</span>");
}

window.onload = function () {
    var src = document.querySelector("pre").textContent;
    document.querySelector("pre").innerHTML = highlight(src);
};
body {
    line-height: 20px;
}
.hl {
    background: rgba(90, 255, 90, 0.2);
    border-radius: 3px;
    padding: 0 3px;
    border: 1px solid #444;
    cursor: default;
}
.hl:hover {
    background: rgba(90, 255, 90, 0.7);
}
<pre>
// everything below should highlight
var a = 1,
    b = 2,
    c = 3;
var d = 5;
var x, y = 3,
z;

z; // this shouldn't highlight

var me = 9, z3 = 10; // these two should highlight

x = x + 1; // this shouldn't

for (var i = 0; i < 5) {} // `i` here should highlight

// these should highlight
var x,y;
var m=19, zzz=12;

// this shouldn't
zzz = 15;

// and all of these should highlight.
var x = 1,
    z = 1.23E4, //comment
    someName = +Infinity,
    u = NaN,
    t = 0x6F, //hexidecimal
    r = 0o37; //octadecimal

// these should both highlight                      
var x, // variable
    y;

// these should be highlighted too
var x, //variable
y;

// and this shouldn't
,
a = 4;
</pre>

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

9 Comments

I just found a bug var x, //variable [newline] y; It captures iable as an identifier so the whitespace after var should be var\s+ and not *
No it doesn't...updated with that example. But, I did fix an issue with inline comments that start with a space, like // comment as opposed to //comment.
@DanielCheung: Okay, I figured out the problem, and it's fixed in the answer now. :)
Remember that this is a preliminary version. We're not here to write an entire parser for you. This is to get you started...I'm sure you can manipulate it to fit your needs.
I agree! Good luck with whatever this is for -- looks like a big project! :)
|

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.