RegEx test for string ending? - javascript

I'm horrible at RegEx and I need a regex to test if a certain string ends a certain way. For example, if the RegEx tests for ending with foo, "somestringfoo" -> True and "someotherFoostring" -> False. It needs to be case sensitive and work with alphanumeric and underscore. Here is what I've got, but I can't get it to work:
var test = RegExp.test('/foo$/');

You would do it this way:
/foo$/.test("somestringfoo")

test is a method of the regexp object, so it would be /foo$/.test(someString) or new Regexp("foo$").test(someString).
However, testing a string for ending with a certain substring does not need regular expressions, see endsWith in JavaScript.

this should do the work:
function isFoo(string){
var pattern = /foo$/;
return pattern.test(string);
}

Related

Test fails when I include an array reference in regex (array with index in regex) JavaScript

I am doing a challenge on freeCodeCamp. I am passed an array with 2 strings, the instructions are to test to see if the letters in the second string are in the first string.
Here's what I have:
return /[arr\[1\]]/gi.test(arr[0]);
This passes all the tests except where it tries to match with a capital letter.
mutation(["hello", "Hello"]) should return true.
It's the only test that fails, I have tested my regex on regexr.com with:
/[Hello]/gi and it matches with 'hello'.
Yes, there are other ways to do it, but why does it fail when I pass the string into the regex from the array?
EDIT: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/mutations
keep in mind that with this: return /[arr\[1\]]/gi.test(arr[0]) you are evaluating exactly this string "arr[1]". test() is a method of RegExp, then to add variables in a regex, or build the regex as string, you should use the RegExp constructor. Like the example below.
See this for browser compatibility of flags.
function mutation(str){
var r = new RegExp(str[0].toLowerCase(), "gi")
return r.test(str[1].toLowerCase());
}
console.log(mutation(["hello", "Hello"]))
The fact that your code passes the test for ["Mary", "Army"] shows that the problem is not one of case sensitivity. The only reason your code passes any of the tests is that /[arr\[1\]]/ looks for matches against the set of characters ar1[] which coincidentally happens to correctly match 8 of the 9 tests. Anyway the other - perhaps biggest - issue is that you are not testing all of the characters in arr[1] against arr[0]; if you run #Emeeus's answer it returns false positives for many of the tests. So, to test all of the characters in arr[1] against arr[0] you need something like this:
function mutation(arr) {
return arr[1].split('').reduce((t, c) => t && new RegExp(c, 'i').test(arr[0]), true);
}
let tests = [
['hello', 'hey'],
["hello", "Hello"],
["zyxwvutsrqponmlkjihgfedcba", "qrstu"],
["Mary", "Army"],
["Mary", "Aarmy"],
["Alien", "line"],
["floor", "for"],
["hello", "neo"],
["voodoo", "no"]
];
tests.map(arr => console.log(arr[0] + ", " + arr[1] + " => " + (mutation(arr) ? 'match' : 'no match')));
JavaScript has a special syntax for Regular Expressions. Those two lines are essentially the same:
return /[arr\[1\]]/gi.test(arr[0]);
return new RegExp('[arr\\[1\\]]', 'gi').test(arr[0]);
but what you probably want is this:
new RegExp('['+arr[1]+']', 'gi').test(arr[0]);
However, you should be careful since this approach does not work if it contains special characters such as '[' or ']'.
Whenever you have a javascript variable in a regular expression, you should construct a new RegExp object. Taken from your question, it should look like this
return new RegExp(arr[1], "gi").test(arr[0]);
As one hint on freeCodeCamp.org says, you can solve the problem easier if you transform the strings into arrays, using the spread operator. No need for regular expressions.
Instead of:
return /[arr\[1\]]/gi.test(arr[0]);
you can do:
return new RegEx(arr[1], gi);
Your code uses a character match ([ ]), not a string match, so it will match anything, that has those characters directly (That's why uppercase and lowercase differs, although you have specified 'i').
The new expression directly uses the string to match, not just the characters.

What RegEx would clean up this set of inputs?

I'm trying to figure out a RegEx that would match the following:
.../string-with-no-spaces -> string-with-no-spaces
or
string-with-no-spaces:... -> string-with-no-spaces
or
.../string-with-no-spaces:... -> string-with-no-spaces
where ... can be anything in these example strings:
example.com:8080/string-with-no-spaces:latest
string-with-no-spaces:latest
example.com:8080/string-with-no-spaces
string-with-no-spaces
and a bonus would be
http://example.com:8080/string-with-no-spaces:latest
and all would match string-with-no-spaces.
Is it possible for a single RegEx to cover all those cases?
So far I've gotten as far as /\/.+(?=:)/ but that not only includes the slash, but only works for case 3. Any ideas?
Edit: Also I should mention that I'm using Node.js, so ideally the solution should pass all of these: https://jsfiddle.net/ys0znLef/
How about:
(?:.*/)?([^/:\s]+)(?::.*|$)
Consider the following solution using specific regex pattern and String.match function:
var re = /(?:[/]|^)([^/:.]+?)(?:[:][^/]|$)/,
// (?:[/]|^) - passive group, checks if the needed string is preceded by '/' or is at start of the text
// (?:[:][^/]|$) - passive group, checks if the needed string is followed by ':' or is at the end of the text
searchString = function(str){
var result = str.match(re);
return result[1];
};
console.log(searchString("example.com:8080/string-with-no-spaces"));
console.log(searchString("string-with-no-spaces:latest"));
console.log(searchString("string-with-no-spaces"));
console.log(searchString("http://example.com:8080/string-with-no-spaces:latest"));
The output for all the cases above will be string-with-no-spaces
Here's the expression I've got... just trying to tweak to use the slash but not include it.
Updated result works in JS
\S([a-zA-Z0-9.:/\-]+)\S
//works on regexr, regex storm, & regex101 - tested with a local html file to confirm JS matches strings
var re = /\S([a-zA-Z0-9.:/\-]+)\S/;

What is the difference between RegExp("str","i") and '/'+"str"+'/i'

I tried to do a case insensitive regular expression search by creating a string like so:
var regEx = '/'+myStr+'/i';
but when I use it in a search, it always returns -1.
If I use:
var regEx = RegExp(myStr,'i');
it works like a champ.
I'd just like to understand why?
You first example will create a string, not a regular expression object.
var myStr = 'test';
var regEx = '/'+myStr+'/i';
console.log(typeof regEx);//string
Using RegExp will create a regular expression object.
var myStr = 'test';
var regEx = RegExp(myStr,'i');
console.log(typeof regEx);//object
Thus when you try to use the search method, you are searching with a string on slashes on both sides, thus getting -1.
var s = 'just a test string';
console.log(s.search('/test/'));//-1
console.log(s.search(/test/));//7
Of course, the string search method can work with a string, in which case it will search for that specific substring, which in your case does not exist, so it returns the -1 index. In your example slashes were being added to the string, rather than producing the intended regular expression.
In JavaScript, there are two ways of creating a regular expression object (short of using code evaluation), a regular expression literal, and one created by the RegExp constructor.
A regular expression literal has to be defined at compile time, and cannot be constructed from string concatenation.
/test/i
To dynamically create a regular expression at runtime, you have to use the RegExp constructor.
RegExp('test', 'i');

Simple Regexp Pattern matching with escape characters

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+

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