Simple Regexp Pattern matching with escape characters - javascript

Hopefully a simple one!
I've been trying to get this to work for several hours now but am having no luck, as I'm fairly new to regexp I may be missing something very obvious here and was hoping someone could point me in the right direction. The pattern I want to match is as follows: -
At least 1 or more numbers + "##" + at least 1 or more numbers + "##" + at least 1 or more numbers
so a few examples of valid combinations would be: -
1##2##3
123#123#123
0##0##0
A few invalid combinations would be
a##b##c
1## ##1
I've got the following regexp like so: -
[\d+]/#/#[\d+]/#/#[\d+]
And am using it like so (note the double slashes as its inside a string): -
var patt = new RegExp("[\\d+]/#/#[\\d+]/#/#[\\d+]");
if(newFieldValue!=patt){newFieldValue=="no match"}
I also tried these but still nothing: -
if(!patt.text(newFieldValue)){newFieldValue==""}
if(patt.text(newFieldValue)){}else{newFieldValue==""}
But nothing I try is matching, where am I going wrong here?
Any pointers gratefully received, cheers!

1) I can't see any reason to use the RegExp constructor over a RegExp literal for your case. (The former is used primarily where the pattern needs to by dynamic, i.e. is contributed to by variables.)
2) You don't need a character class if there's only one type of character in it (so \d+ not [\d+]
3) You are not actually checking the pattern against the input. You don't apply RegEx by creating an instance of it and using ==; you need to use test() or match() to see if a match is made (the former if you want to check only, not capture)
4) You have == where you mean to assign (=)
if (!/\d+##\d+##\d+/.test(newFieldValue)) newFieldValue = "no match";

You put + inside the brackets, so you're matching a single character that's either a digit or +, not a sequence of digits. I also don't understand why you have / before each #, your description doesn't mention anything about this character.
Use:
var patt = /\d+##\d+##\d+/;

You should use the test method of the pat regex
if (!patt.test(newFieldValue)){ newFieldValue=="no match"; }
once you have a valid regular expression.

Try this regex :
^(?:\d+##){2}\d+$
Demo: http://regex101.com/r/mE8aG7
With the following regex
[\d+]/#/#[\d+]/#/#[\d+]
You would only match things like:
+/#/#5/#/#+
+/#/#+/#/#+
0/#/#0/#/#0
because the regex engine sees it like on the schema below:

Something like:
((-\s)?\d+##)+\d+

Related

javascript regex insert new element into expression

I am passing a URL to a block of code in which I need to insert a new element into the regex. Pretty sure the regex is valid and the code seems right but no matter what I can't seem to execute the match for regex!
//** Incoming url's
//** url e.g. api/223344
//** api/11aa/page/2017
//** Need to match to the following
//** dir/api/12ab/page/1999
//** Hence the need to add dir at the front
var url = req.url;
//** pass in: /^\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var re = myregex.toString();
//** Insert dir into regex: /^dir\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var regVar = re.substr(0, 2) + 'dir' + re.substr(2);
var matchedData = url.match(regVar);
matchedData === null ? console.log('NO') : console.log('Yay');
I hope I am just missing the obvious but can anyone see why I can't match and always returns NO?
Thanks
Let's break down your regex
^\/api\/ this matches the beginning of a string, and it looks to match exactly the string "/api"
([a-zA-Z0-9-_~ %]+) this is a capturing group: this one specifically will capture anything inside those brackets, with the + indicating to capture 1 or more, so for example, this section will match abAB25-_ %
(?:\/page\/([a-zA-Z0-9-_~ %]+)) this groups multiple tokens together as well, but does not create a capturing group like above (the ?: makes it non-captuing). You are first matching a string exactly like "/page/" followed by a group exactly like mentioned in the paragraph above (that matches a-z, A-Z, 0-9, etc.
?$ is at the end, and the ? means capture 0 or more of the precending group, and the $ matches the end of the string
This regex will match this string, for example: /api/abAB25-_ %/page/abAB25-_ %
You may be able to take advantage of capturing groups, however, and use something like this instead to get similar results: ^\/api\/([a-zA-Z0-9-_~ %]+)\/page\/\1?$. Here, we are using \1 to reference that first capturing group and match exactly the same tokens it is matching. EDIT: actually, this probably won't work, since the text after /api/ and the text after /page/ will most likely be different, carrying on...
Afterwards, you are are adding "dir" to the beginning of your search, so you can now match someting like this: dir/api/abAB25-_ %/page/abAB25-_ %
You have also now converted the regex to a string, so like Crayon Violent pointed out in their comment, this will break your expected funtionality. You can fix this by using .source on your regex: var matchedData = url.match(regVar.source); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
Now you can properly match a string like this: dir/api/11aa/page/2017 see this example: https://repl.it/Mj8h
As mentioned by Crayon Violent in the comments, it seems you're passing a String rather than a regular expression in the .match() function. maybe try the following:
url.match(new RegExp(regVar, "i"));
to convert the string to a regular expression. The "i" is for ignore case; don't know that's what you want. Learn more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Regular Expression - Match String Not Preceded by Another String (JavaScript)

I am trying to find a regular expression that will match a string when it's NOT preceded by another specific string (in my case, when it is NOT preceded by "http://"). This is in JavaScript, and I'm running on Chrome (not that it should matter).
The sample code is:
var str = 'http://www.stackoverflow.com www.stackoverflow.com';
alert(str.replace(new RegExp('SOMETHING','g'),'rocks'));
And I want to replace SOMETHING with a regular expression that means "match www.stackoverflow.com unless it's preceded by http://". The alert should then say "http://www.stackoverflow.com rocks", naturally.
Can anyone help? It feels like I tried everything found in previous answers, but nothing works. Thanks!
As JavaScript regex engines don't support 'lookbehind' assertions, it's not possible to do with plain regex. Still, there's a workaround, involving replace callback function:
var str = "As http://JavaScript regex engines don't support `lookbehind`, it's not possible to do with plain regex. Still, there's a workaround";
var adjusted = str.replace(/\S+/g, function(match) {
return match.slice(0, 7) === 'http://'
? match
: 'rocks'
});
console.log(adjusted);
You can actually create a generator for these functions:
var replaceIfNotPrecededBy = function(notPrecededBy, replacement) {
return function(match) {
return match.slice(0, notPrecededBy.length) === notPrecededBy
? match
: replacement;
}
};
... then use it in that replace instead:
var adjusted = str.replace(/\S+/g, replaceIfNotPrecededBy('http://', 'rocks'));
JS Fiddle.
raina77ow's answer reflected the situation in 2013, but it is now outdated, as the proposal for lookbehind assertions got accepted into the ECMAScript spec in 2018.
See docs for it on MDN:
Characters
Meaning
(?<!y)x
Negative lookbehind assertion: Matches "x" only if "x" is not preceded by "y". For example, /(?<!-)\d+/ matches a number only if it is not preceded by a minus sign. /(?<!-)\d+/.exec('3') matches "3". /(?<!-)\d+/.exec('-3') match is not found because the number is preceded by the minus sign.
Therefore, you can now express "match www.stackoverflow.com unless it's preceded by http://" as /(?<!http:\/\/)www.stackoverflow.com/:
const str = 'http://www.stackoverflow.com www.stackoverflow.com';
console.log(str.replace(/(?<!http:\/\/)www.stackoverflow.com/g, 'rocks'));
This also works:
var variable = 'http://www.example.com www.example.com';
alert(variable.replace(new RegExp('([^(http:\/\/)|(https:\/\/)])(www.example.com)','g'),'$1rocks'));
The alert says "http://www.example.com rocks".

Javascript string validation using the regex object

I am complete novice at regex and Javascript. I have the following problem: need to check into a textfield the existence of one (1) or many (n) consecutive * (asterisk) character/characters eg. * or ** or *** or infinite (n) *. Strings allowed eg. *tomato or tomato* or **tomato or tomato** or as many(n)*tomato many(n)*. So, far I had tried the following:
var str = 'a string'
var value = encodeURIComponent(str);
var reg = /([^\s]\*)|(\*[^\s])/;
if (reg.test(value) == true ) {
alert ('Watch out your asterisks!!!')
}
By your question it's hard to decipher what you're after... But let me try:
Only allow asterisks at beginning or at end
If you only allow an arbitrary number (at least one) of asterisks either at the beginning or at the end (but not on both sides) like:
*****tomato
tomato******
but not **tomato*****
Then use this regular expression:
reg = /^(?:\*+[^*]+|[^*]+\*+)$/;
Match front and back number of asterisks
If you require that the number of asterisks at the biginning matches number of asterisks at the end like
*****tomato*****
*tomato*
but not **tomato*****
then use this regular expression:
reg = /^(\*+)[^*]+\1$/;
Results?
It's unclear from your question what the results should be when each of these regular expressions match? Are strings that test positive to above regular expressions fine or wrong is on you and your requirements. As long as you have correct regular expressions you're good to go and provide the functionality you require.
I've also written my regular expressions to just exclude asterisks within the string. If you also need to reject spaces or anything else simply adjust the [^...] parts of above expressions.
Note: both regular expressions are untested but should get you started to build the one you actually need and require in your code.
If I understand correctly you're looking for a pattern like this:
var pattern = /\**[^\s*]+\**/;
this won't match strings like ***** or ** ***, but will match ***d*** *d or all of your examples that you say are valid (***tomatos etc).If I misunderstood, let me know and I'll see what I can do to help. PS: we all started out as newbies at some point, nothing to be ashamed of, let alone apologize for :)
After the edit to your question I gather the use of an asterisk is required, either at the beginning or end of the input, but the string must also contain at least 1 other character, so I propose the following solution:
var pattern = /^\*+[^\s*]+|[^\s*]+\*+$/;
'****'.match(pattern);//false
' ***tomato**'.match(pattern);//true
If, however *tomato* is not allowed, you'll have to change the regex to:
var pattern = /^\*+[^\s*]+$|^[^\s*]+\*+$/;
Here's a handy site to help you find your way in the magical world of regular expressions.

Javascript regex match for string "game_1"

I just can't get this thing to work in javascript. So, I have a text "game_1" without the quotes and now i want to get that number out of it and I tried this:
var idText = "game_1";
re = /game_(.*?)/;
found = idText.match(re);
var ajdi = found[1];
alert( ajdi );
But it doesn't work - please point out where am I going wrong.
If you're only matching a number, you may want to try
/game_([0-9]+)/
as your regular expression. That will match at least one number, which seems to be what you need. You entered a regexp that allows for 0 characters (*) and let it select the shortest possible result (?), which may be a problem (and match you 0 characters), depending on the regex engine.
If this is the complete text, then there is no need for regular expressions:
var id = +str.split('_')[1];
or
var id = +str.replace('game_', '');
(unary + is to convert the string to a number)
If you insist on regular expression, you have to anchor the expression:
/^game_(.*?)$/
or make the * greedy by omitting the ?:
/game_(.*)/
Better is to make the expression more restrictive as #Naltharial suggested.
Simple string manipulation:
var idText = "game_1",
adji = parseInt(idText.substring(5), 10);
* means zero or more occurrences. It seems that combining it with a greediness controller ? results in zero match.
You could replace * with + (which means one or more occurrences), but as #Felix Kling notes, it would only match one digit.
Better to ditch the ? completely.
http://jsfiddle.net/G8Qt7/2/
Try "game_1".replace(/^(game_)/, '')
this will return the number
You can simply use this re /\d+/ to get any number inside your string

Regex equivalent to str.substr(0, str.indexOf('foo'))

Given this string:
var str = 'A1=B2;C3,D0*E9+F6-';
I would like to retrieve the substring that goes from the beginning of the string up to 'D0*' (excluding), in this case:
'A1=B2;C3,'
I know how to achieve this using the combination of the substr and indexOf methods:
str.substr(0, str.indexOf('D0*'))
Live demo: http://jsfiddle.net/simevidas/XSu22/
However, this is obviously not the best solution since it contains a redundancy (the str name has to be written twice). This redundancy can be avoided by using the match method together with a regular expression that captures the substring:
str.match(/???/)[1]
Which regular expression literal do we have to pass into match to ensure that the correct substring is returned?
My guess is this: /(.*)D0\*/ (and that works), but my experience with regular expressions is rather limited, so I'm going to need a confirmation...
Try this:
/(.*?)D0\*/.exec(str)[1]
Or:
str.match(/(.*?)D0\*/)[1]
DEMO HERE
? directly following a quantifier makes the quantifier non-greedy (makes it match minimum instead of maximum of the interval defined).
Here's where that's from
/^(.+?)D0\*/
Try it here: http://rubular.com/r/TNTizJLSn9
/^.*(?=D0\*)/
more text to hit character limit...
You can do a number-group, like your example.
/^(.*?)foo/
It mean somethink like:
Store all in group, from start (the 0)
Stop, but don't store on found foo (the indexOf)
After that, you need match and get
'hello foo bar foo bar'.match(/^(.*?)foo/)[1]; // will return "hello "
It mean that will work on str variable and get the first (and unique) number-group existent. The [0] instead [1] mean that will get all matched code.
Bye :)

Categories

Resources