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

Get exact match of a word using RegEx

I'm attempting to get the exact match of a word, but I just can't seem to get it. I have never made a foray into regular expressions before, so this is all brand new to me.

I want to search the string, see if an exact word is in there, and only return a positive index if that exact word is there. This example below will still return a location value that is above -1 because "cos" is within "acosh". I need to check to see if "cos" by itself is a part of this string or a way for me to check for certain characters around "cos".

var str = "Math.acosh(1)+Math.sin(Math.PI/3)";
if (str.search(/cos/g) > -1) {
  alert("cos was found");
} else {
  alert("cos was not found!");
}

Thanks! :)

1 Answer

Hello potential relative!

You're right in that regular expressions will match within words. If you're attempting to match whole words within a string you need to specify that the surrounding characters be non-word characters (anything except A-Z, 0-9, and underscores). \W (note the capital 'W') will handle matching all non-word characters for us so we just surround our target word; a basic example looks something like this:

"foo bar cos baz".match(/\Wcos\W/)    // Finds a match
"foo bar acos baz".match(/\Wcos\W/)   // Does not find a match

This however doesn't take into account matching words at the beginning or end of the string (e.g. "foo bar baz cos"). For that you'll need to allow for the beginning and end of the string to be matched instead of a non-word character with ^ and $ respectively. In this case we use a group with the or operator |. (^|\W) matches either the beginning of the string ^ or a non-word character \W.

"cos foo bar baz".match(/(^|\W)cos($|\W)/)    // Finds a match
"acos foo bar baz".match(/(^|\W)cos($|\W)/)   // Does not find a match
"foo bar baz cos".match(/(^|\W)cos($|\W)/)    // Finds a match
"foo bar baz acos".match(/(^|\W)cos($|\W)/)   // Does not find a match

Finally i'd throw in the i modifier to make it case-insensitive so you can match "COS", "cos", and everything in between. Unless of course you only want lowercase, then leave it out!

/(^|\W)cos($|\W)/i

Alternatively you could use the split method on String combined with jQuery's inArray() (eventually similar functionality to inArray will be part of the javascript standard, but not yet).

  if( $.inArray("cos", "foo bar baz cos".split(" ")) > -1 ) {

  }

You are a life saver, my potential relative! :D I was starting to get a MASSIVE headache from this regular expression stuff, but this was awesome!

I live in West Virginia, but all of my Parsons family is from the Southeastern Ohio/Northwestern West Virginia area haha If you have family in that area, we may just be kinfolk haha :D

I spoke too soon.

I should go into more detail, so that you can see what I'm trying to do. I have a calculator program on my website I've been forming located here and what I'm allowing users to do is to just type in (or insert via buttons) Math objects/methods without having to prepend them with "Math." i.e. "cos(pi/3)" is converted into "Math.cos(Math.PI/3)". This system has worked tremendously until I started introducing a new JS script where I am implementing the newer, experimental Math methods such as "acosh".

The new RegEx you've given me worked for so that "acosh" wasn't converted into "aMath" in the evaluation. But, now "cos" is no longer defined. And when I pass it the string "acosh(1)+cos(pi/3)" it becomes "aMath.cosh(1)+cos(Math.PI/3)" because it finds that first "cos" within "acosh".

The entirety of the script is located at my website on the page I linked to but as a warning, it is rather large lol This is a modified example of an evaluation done on the page:

var $mathKeywords = ["E", "LN2", "LN10", "LOG2E", "LOG10E", "PI", "SQRT1_2", "SQRT2", "abs", "acos", "asin", "asinh", "atan", "atan2", "atanh", "cbrt", "ceil", "clz32", "cos", "exp", "expm1", "floor", "fround", "hypot", "imul", "log1p", "log10", "log2", "max", "min", "pow", "random", "round", "sin", "sinh", "sqrt", "tan", "tanh", "trunc"];

var $resultVal = "acosh(1)+cos(PI/3)".toLowerCase();
  try {
//Iterate over each Math object/method
 $.each($mathKeywords, function (i, val) {
//Convert val within array to a lower case form
var $lowerKey = val.toLowerCase();
var pattern = new RegExp("(^|\\W)" + $lowerKey + "($|\\W)");
//See if pattern gives a match within $resultVal
var $location = $resultVal.match(pattern);
//Math keyword is found
if ($location != null) {
//replace the lowercase version of the math keyword with its properly cased version prepended 
//with Math. i.e. cos becomes Math.cos and pi becomes Math.PI
$resultVal = $resultVal.replace($lowerKey, "Math." + val);
}
 });
//Set the result element's value to an evaluation of $resultVal
//A better implementation of eval exists on the actual calculator program
alert($resultVal);
alert(eval($resultVal));
}
catch (err) {
  alert("Error: Cannot process expression due to " + err + ".");
}

I finally had someone help me on Stack Overflow! Geoff, your answer was very good, though, and got me headed in the right direction. Thanks again, potential relative!