n as
n as

Reputation: 619

Match Word that Starts and Ends with

This must be somewhere... but after wasting quite a bit of time, I can't find it: I would like to test a string matching: "in"+ * +"ing".

In other words,
"interesting" should result in true, whereas
"insist" and "string" should fail.

I am only interested in testing a single word, with no spaces.

I know I could do this in two tests, but I really want to do it one. As always, thanks for any help.

Upvotes: 17

Views: 25118

Answers (5)

Ryszard Czech
Ryszard Czech

Reputation: 18611

If in in the first rule can be part of ing (the second rule) use

/\b(?=in)(?=\w*ing\b)\w+/g

See proof.

Explanation

--------------------------------------------------------------------------------
  \b                       the boundary between a word char (\w) and
                           something that is not a word char
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    in                       'in'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    \w*                      word characters (a-z, A-Z, 0-9, _) (0 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    ing                      'ing'
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                           more times (matching the most amount
                           possible))

If in can't be part of ing use

/\bin\w*ing\b/g

See proof.

Explanation

--------------------------------------------------------------------------------
  \b                       the boundary between a word char (\w) and
                           something that is not a word char
--------------------------------------------------------------------------------
  in                       'in'
--------------------------------------------------------------------------------
  \w*                      word characters (a-z, A-Z, 0-9, _) (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  ing                      'ing'
--------------------------------------------------------------------------------
  \b                       the boundary between a word char (\w) and
                           something that is not a word char

JavaScript*:

const string = 'interesting,ing and bing.';
const rx_1 = /\b(?=in)(?=\w*ing\b)\w+/g;
const rx_2 = /\bin\w*ing\b/g;
console.log(string.match(rx_1));
console.log(string.match(rx_2));

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150030

If you specifically want to match words then try something like this:

/in[a-z]*ing/i

If you want "in" followed by any characters at all followed by "ing" then:

/in.*ing/i

The i after the second / makes it case insensitive. Either way replace the * with + if you want to have at least one character in between "in" and "ing"; * matches zero or more.

Given a variable in a string you could use the regex to test for a match like this:

var str = "Interesting";
if (/in[a-z]*ing/i.test(str)) {
    // we have a match
}

UPDATE

"What if the prefix and suffix are stored in variables?"

Well then instead of using a regex literal as shown above you'd use new RegExp() and pass a string representing the pattern.

var prefix = "in",
    suffix = "ing",
    re = new RegExp(prefix + "[a-z]*" + suffix, "i");
if (re.match("Interesting")) {
    // we have a match
}

All of the regular expressions I've shown so far will match the "in" something "ing" pattern anywhere within a larger string. If the idea is to test whether the entire string matches that mattern such that "interesting" would be a match but "noninterestingstuff" would not (as per stackunderflow's comment) then you need to match the start and end of the string with ^ and $:

/^in[a-z]*ing$/i

Or from variables:

new RegExp("^" + p + "[a-z]*" + s + "$", "i")

Or if you're testing the whole string you don't necessarily need regex (although I find regex simpler):

var str = "Interesting",
    prefix = "in",
    suffix = "ing";
str = str.toLowerCase(); // if case is not important

if (str.indexOf(prefix)===0 && str.endsWith(suffix)){
   // match do something
}

Or for browsers that don't support .endsWith():

if (str.slice(0,prefix.length)===prefix && str.slice(-suffix.length)===suffix)

"What's the best I can read on the subject?"

MDN gives a rundown of regex for JavaScript. regular-expressions.info gives a more general set of tutorials.

Upvotes: 17

stackunderflow
stackunderflow

Reputation: 993

I would recommend matching word boundary as well.

Here's a fully parameterized version:

Code

(function(prefix, suffix, anchored, flags) {
    var tests = [
        "noninterestingtypo",
        "mining",
        "in8ping",
        "interesting"];
    var re = new RegExp(
    (anchored ? '\\b' : '') + prefix + '[a-z]+' + suffix + (anchored ? '\\b' : ''), flags);
    var reportMatch = function(value) {
        console.log(value.match(re) ? value + " matches" : value + " does not match");
    };
    tests.forEach(reportMatch);
})( /* prefix, suffix, anchored, flags */
    "in", "ing", true, "i");

Output

noninterestingtypo does not match
mining does not match
in8ping does not match
interesting matches

Just expand the test string array and see what happens without the \b.

Upvotes: 0

Alex Wayne
Alex Wayne

Reputation: 187034

/in.+ing/ // a string that has `in` then at least one character, then `ing`


/in.+ing/.test('interesting'); // true
/in.+ing/.test('insist');      // false
/in.+ing/.test('string');      // false

/in.+ing/.test('ining'); // false, .+ means at least one character is required.
/in.*ing/.test('ining'); // true, .* means zero or more characters are allowed.

If you wanted to constrain things to just one word, you could use the \w word character shorthand.

/in\w+ing/.test('invents tiring') // false, space is not a "word" character.
/in.+ing/.test('invents tiring') // true, dot matches any character, even space

Upvotes: 5

SomeKittens
SomeKittens

Reputation: 39532

The regex you're looking for is /in.*ing/ (this includes all characters).

If you're more interested in single words, use a character class /in[a-z]*ing/

You can add the i flag if you're not interested in case.

Upvotes: 1

Related Questions