Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Regarding the regex course - create a variable newText, and assign a replacement string to that variable.

I took this question:

The question is currently phrased:

This challenge contains a form that will accept a first and last name (separated with a space), and display the last name first, then a comma, then the first name. Your challenge is to create a variable newText, and assign a replacement string to that variable. Be careful to match the exact variable name, because that's what is passed into replace(). You'll also need to reference the values captured by the parentheses in the regex.

This is my answer for it:

function reformatName(text) {
  const rawName = /^(\w+)\s(\w+)$/;

  // Type your answer on line 5, below:

var newText = '$ $1, $2';

  return text.replace(rawName, newText);
}

From the comment, I understand the answer should be in a single row:

I declared a var, added a dollar sign to match anything ending with the following 2 captured groups of characters, added a space, and than 2 dollar signs with relative numbers to access the two captured groups, separated by a comma.

This the error I get (I believe it should be edited to be more clear):

'reformatName returns a string, but it's not the expected output. Check the string in 'newText'. Remember, you'll need to use the stored values captured from the original string.

I tried to watch each of the 3 videos again but didn't found out what's bad with the code.

Dear Joel Kraft I'd appreciate your reply.

2 Answers

Dear Ben Aharoni ,

It seems to me like you're not using them in the right order, and also you're not being consistent with the JS syntax.

If, like Dale mentioned above, you put them in order and use the same syntax used in the rest of the js file (the ES2015), then you shouldn't have any problem.

function reformatName(text) {
  const rawName = /^(\w+)\s(\w+)$/;

  // Type your answer on line 5, below:
  const newText = '$2, $1';   // $2 is going to be your last name, right? 
                                            // And $1 your first name.

  return text.replace(rawName, newText);
}

Thanks Nico. That worked, but why does the first dollar sign make it not to work? As I understand, Joel used that in an adjacent video to match anything ending with the following 2 captured groups of characters. I was consisted to the dollar sign as seen in the video...

Also, why we need to flip them manually (from $1, $2 to $2, $1)? I thought that the returned text.replace will do that for us...

Interesting question, Ben. Not really. It won't.

Let me show you what each of these do:

function reformatName(text) {


// This one is a regex, i.e.: it's not any specific value or word/s.
// What this one is saying is: 'match any string that starts with one word, then has a space,
// and then ends with another word'.
    const rawName = /^(\w+)\s(\w+)$/;


// Now this one also, is not any specific word or value.
// This (when and only if used with a regex and the replace method)
// is just saying something like: 'if you provide me a regex in a replace(),
// then I will be the result of swapping the second part and the first one,
// adding a comma and a space in between them' like Dale mentioned.
// Notice that by itself it doesn't do anything, and
// it still does not hold anything else than that string: '$2, $1'.
// Needs to be used with a regex and the replace()
// to have any effect
    const newText = '$2, $1';


// The next line is key. This is the line that actually makes the swap.
// This one states: take rawName (a regex with the pattern above)
// and swap it according to what the newText states.
// Notice the return? Well, since this is a function, it still is not doing anything.
// It is only being defined, but everytime this function is called
// and receives a 'text' arg, it will do to it according to all what we mentioned above. 
    return text.replace(rawName, newText);
}

I hope that made it clearer, especially where your doubts are? If you still have doubts, though, don't restrain, just follow it up here. :)

I now understand - we do need to define newText manually in an opposite way to rawName (what's being matched by the regex), but the actual replacement of rawText in newText, as will be seen by the client, is being made with the returned text.replace.

But I still miss why Joel used an extra dollar sign ($ $1 $2) in his video example, but in this question he didn't ($2 $1).

I ask it since I understand from him in the video that it uses to match anything ending with the following 2 captured groups of characters.

To the first part of your comment: Exactly!

To the second part of your comment. Not exactly. He used more dollar signs in his video example because he was using a price for the example (and also intentionally to explain how to escape the actual dollar sign).

Here you go:

let string = '5337'
let regex = /(\d*)(\d{2})/
let replacement = '$ $1.$2' // The $ here behaves as an actual dollar sign, 
                            // it's not replacing anything, even if used with replace().
string.replace(regex, replacement)
// Outputs: '$ 53.37'. Notice the literal '$'.
// Try it yourself in the console and you'll see.

/***********/
//NEXT:

//Now, he wanted to have the actual dollar sign together with the price in the output, 
// like '$20.25' (instead of '$ 20.25') for example. So he does:
replacement = '$$1.$2'
string.replace(regex, replacement)
// Outputs '$1.37' instead of '$53.37' like we expected. Wait, what? I hear you say :)

// The reason is $$ is the way to escape the dollar sign.
// Think of this: if you want to display the text '$1' (instead of using it to replace anything)
// how would you do? There you go: That's when you need to escape it.
// Otherwise '$1' will replace it for the first value, not give you literally '$1'.

/***********/
//LAST:

//Now, however, what we want is to achieve the '$53.37' thing, right?
// So this is the way to do that:
replacement = '$$$1.$2'   /* I know that you'll tell me that's a lot of money! :)  */
string.replace(regex, replacement)
// Outputs '$53.37', just like we wanted. Why?
// Because the first two dollar signs will actually display literally a dollar sign,
// and then the remaining ones will perform the replacements of $1 for 53,
// and of $2 for 37.
// Does that feel clearer now?

I thought that the first dollar sign uses us to match anything ending with the following 2 captured groups of characters, because Joel says in the first video:

For the replacement string, We want to start with a $ sign, space, then the first captured group, a decimal and the second captured group.

I feel it a bit confused me, because it doesn't literally mean something like "I used it just to display a dollar sign for the price".

Anyway, dear Nico Trivelli, I no longer have this confusion. I now fully understand both examples as well as the "special" (non backslash) dollar sign escaping Joel used when the first dollar sign just escapes the second right after it, and that the second won't have any effect on the third which will just access the (first) caged group.

The order for this is very important. The last name is supposed to be first. '$2'. Then it needs a comma. ', ' And finally the first name. '$1'

AFAIK, the coming return text.replace(rawName, newText); Will do that re sorting (plus adding the comma), but still it doesn't happen.