roryhewitt
roryhewitt

Reputation: 4507

Regex for token replacement in JavaScript

I have a very specific requirement in JavaScript, and I'm wondering if anyone can help.

I'm looking for a validation Regex that I can use to validate tokens in a string. Each token is in the following format:

(__([A-Z1-9_])+__)

IOW, two underscores, following by any number of upper-case characters, digits or underscores, and ending with another two underscores. Examples might be:

__A_TOKEN__
__ANOTHER_1T_O_K_E_N__

A token cannot contain two underscores, so the following would be invalid:

__A__TOKEN__

Finally, there could be multiple tokens in the string, with or without other leading or trailing characters, like this:

http://__DOMAIN__/__PATH__/logs/__LOGFILE__.log

Theoretically, there could even be two tokens right next to one another, e.g.:

__TOKEN_A____TOKEN_B__

I've been playing with regex's for a while, but this has me stumped as to how to validate. It's easy enough to simply check for a single token with optional leading/trailing text, with this:

^(.*)?(__([A-Z1-9_])+__)+(.*)?$

but how can I check for multiple tokens, like this (which will validate using the above regex):

xxx__UPPERCASE__yyy__lowercase__

which shouldn't be allowed, since __lowercase__ isn't a valid token.

Is this something which is best validated programatically rather than with a regex?

Upvotes: 0

Views: 474

Answers (2)

Nathan
Nathan

Reputation: 1482

This takes into account the rules you provided by using a negative look behind.

var str = "__TOKEN_A____TOKEN_B__"; 
var res = str.match(/__(?:(?!__)[A-Z1-9_])+__/g);
alert(res);

Regex

/__(?:(?!__)[A-Z1-9_])+__/g

Explanation

__            -- Match the two underscores (the start of a token)
(?:           -- Non-capturing group
 (?!__)       -- Negative look behind to check if we're starting a new token
 [A-Z1-9_]    -- Valid characters within the token
)+            -- Allow one or more valid characters
__            -- The ending token sequence of two underscores

Upvotes: 1

Ismael Miguel
Ismael Miguel

Reputation: 4241

I have a solution for you:

/__([A-Z\d]+(?:_[A-Z\d]+)*)__/g

Yes, there is a repetition there, but it's straight forward to change.

You can check it here in action on this link: http://regex101.com/r/zZ6cC3/1

Upvotes: 1

Related Questions