I have an alternate solution for the problem Remove Whitespace from Start and End that seems like it works—my solution returns “Hello, World!” with no spaces according to console.log()—but it fails the test. And if I test the “Hello, World!” that I get for equality against the “Hello, World!” returned by the official solution, the test returns false. So they look equal, but somehow they are not equal.
Here is what I used to test this, with my solution at the top, the official solution at the bottom, and some console.log() statements and equality tests built in (you can try a live version at this Repl.it page:
// My solution - fails test
let hello = " Hello, World! ";
let wsRegex = /^(\s*)(.+)(\s*)$/;
let result = hello.replace(wsRegex, "$2");
console.log("my result = " + result) // prints Hello, World!
// FreeCodeCamp solution - passes test
let hello2 = " Hello, World! ";
let wsRegex2 = /^\s+|\s+$/g;
let result2 = hello2.replace(wsRegex2, "");
console.log("FCC result = " + result2) // also prints Hello, World!
console.log("testing loose equality: " + (result == result2)); // returns FALSE - why?
console.log("testing strict equality: " + (result === result2)); // returns FALSE - why?
yeah you were right, now your gonna have to explain to me how the or statement matches both sides lol, cuz i always throught it as one or the other, sorry im not that clued up on regex but i always thought it meant one or the other just like if i use something like this const name = 'bob' || 'sam' its only gonna be one of them? or am i wrong? how can both sides be true? i dont see how this is possible without a loop, i would love to know how this works please @colinthornton is it just one big loop that runs untill it all matches? regex is so hard to understand
@biscuitmanz The regex you posted is from the solution that passes, I was showing that @bhagerty 's solution doesn’t pass the requirements as he expected.
/^\s+|\s+$/g
The above regex matches
^\s+ one or more whitespace characters at the beginning of a string
| OR
\s+$ one or more whitespace characters at the end of a string
g globally, can make multiple matches (this is why it matches both the leading and trailing whitespace, and the replace method in the solution replaces those matches with empty strings, ie, removing them).
I like using this tool when working with regular expressions.
this is greedy, it’s taking as much as possible while making sure that also the next group match - as the next group is satisfied with also 0 characters, the .+ match till the end of the string
if you want to use this, just return to the concept of greedy and lazy matching and how to fix that
In case you’re interested, here’s the regex I used to solve the problem after your comments:
/^(\s*)(.+[^\s*$])(\s*)$/
This is more complicated than the official solution, but it conceptually makes sense to me and uses the concepts of collection groups from the previous exercises. Basically, this now has three parts: (1) ^(\s*) says “match whitespace (if any) at the beginning”; (2) (.+[^\s$]) says “match everything in the middle, up until you get to trailing whitespace (if any), which does not match”; and (3) (\s*) says “match trailing whitespace (if any).” Then the expression is rewritten keeping just the middle capture group, i.e., everything but the trailing and leading whitespace.
That was the solution I was trying, I realised the $2 is capturing the trailing white space, and then reinserting it when we use the replace function.
So I did the following
let wsRegex = /\s+(.*\S)\s+$/; // Change this line
let result = hello.replace(wsRegex, "$1"); // Change this line
Basically the (.*) like your (.+) was picking up the whitespace also, and storing it in the $2 variable. What the \S (capital S) did was the same as [^\s].
that’s why you use lazy matching, in that way it captures enough to satisfy the pattern but the least number of characters possible, meaning the spaces are left for the other capture groups