-1

Related: Regex - Match whole string

I want a given regexp to match the whole string. For example, when given a regexp /abc/, it should only match string "abc" but not "abcd". I have searched the above question, which has somehow a similar situation than mine. The difference here is that the regexp is not directly written in my code. So I can't change /abc/ to /^abc$/ directly in the source code.

Let's say, I want a function which takes two arguments: a 'regexp' (e.g. /abc/) and a string (e.g. 'abc'). The function returns matched result if and only if the given regexp matches the whole string, but returns null otherwise.

What I'm trying:

function match(regexp, string) {
  var parse = /\/(.*)\/(.*)/.exec(regexp);
  var reg = new RegExp('^' + parse[1] + '$', parse[2]);
  return string.match(reg);
}

Is this code correct? Any better way to do so?

tsh
  • 4,263
  • 5
  • 28
  • 47
  • You should provide example inputs and show what you want as an output vs. what's the actual output – Nir Alfasi Nov 29 '17 at 03:23
  • @alfasin anything not clearly? maybe "for example, I want `match(/abc/, 'abc')` return truthy and `match(/abc/, 'abc1')` return falsy" just like the what said in the linked post? Yes, the given code does work on this certain testcase, but I'm not sure if there is any other situations may break this code. – tsh Nov 29 '17 at 03:29
  • No it's not clear. I still don't understand what you're asking... – Nir Alfasi Nov 29 '17 at 03:31
  • @alfasin any better now? I've no idea how to make it more clearly... – tsh Nov 29 '17 at 03:46
  • Your code is working for input `console.log(match(/abc/g,'abc')); console.log(match(/abc/g,'abcd'));` – Hassan Imam Nov 29 '17 at 03:51
  • @HassanImam yes, I know that. I had tested these two testcase before I post it. But I'm asking if there are any testcases I had not found which may break this code. And maybe the better way to do so. – tsh Nov 29 '17 at 03:52
  • @tsh you want only the **word** `abc` not the **word** `1abc`, not the **word** `abcdefg`, correct? – zer00ne Nov 29 '17 at 05:27
  • 3
    Possible duplicate of [Regex - Match whole string](https://stackoverflow.com/questions/6298566/regex-match-whole-string) – SamWhan Nov 29 '17 at 09:19
  • @ClasG had you read the post? – tsh Nov 29 '17 at 09:23
  • Maybe I'm missing something, but to me it seems as simple as adding the anchors. [See this fiddle](https://jsfiddle.net/gthx157f/). – SamWhan Nov 29 '17 at 09:41
  • @ClasG This may be an answer instead of comment. But still some issues: 1. it will fail if `regexp` has any flags; 2. as [le_m](https://stackoverflow.com/users/1647737/le-m) pointed out in [the answer](https://stackoverflow.com/a/47545554/2045384), if `regexp` is `/a+|b+/`, it will incorrectly match `"xb"`. – tsh Nov 29 '17 at 09:44
  • So... It's a bit more complex, but it's still a matter of adding the anchors ;) (And it's basically the one you have in the question). [Fiddle here](https://jsfiddle.net/gthx157f/2/). If the question was "How can I manipulate a JS RegExp as a string?" it wouldn't be a *dup* of the "Related" question, but as it is now, it is (IMO). – SamWhan Nov 29 '17 at 10:16

1 Answers1

1

You transform regex such as /a+|b+/ into ^a+|b+$ which still matches e.g. 'xbb'. A solution would be to wrap the inner regex with an anonymous group: ^(?:a+|b+)$.

Also, you currently truncate useful regex flags such as /.../m or /.../i.

Alternatively, you could simply use the original regex and check if the result covers the whole input string length:

function fullmatch(regex, string) {
  const result = string.match(regex);
  return !!result && result[0].length === string.length;
}

// Example:
console.log(fullmatch(/a+|b+/, 'xbb')); // false
console.log(fullmatch(/a+|b+/, 'bbb')); // true

// Respects lazy quantifier:
console.log(fullmatch(/b+?/, 'bbb'));   // false
console.log(fullmatch(/b+/, 'bbb'));    // true

// Invariant to global flag g:
console.log(fullmatch(/b+?/g, 'bbb'));  // false
console.log(fullmatch(/b+/g, 'bbb'));   // true
le_m
  • 19,302
  • 9
  • 64
  • 74
  • checking matched length do not always provide same result than adding `^` and `$`, `'abcc'.match(/abc+?/)[0].length === 3` but `'abcc'.match(/^abc+?$/)[0].length === 4`. – tsh Nov 29 '17 at 05:20