Typeahead Invalid regular expression: /(/:

1.3k views Asked by At

I've add a typeahead search. Everithing is working but I've found one issue. I have text in my json for example "Hi, my name is Jason (Mckay) and ..."

When I try to type some words from this string everithin is ok, but when I'll type "(" or ")" I will have an exception:

Uncaught SyntaxError: Invalid regular expression: /(/: Unterminated group

I was look into typeahead "the Basics" and have the same error:

https://twitter.github.io/typeahead.js/examples/#prefetch

The same when I'll try to input any nubmers first "1", "2" etc...

Here is my default substringMatcher where is the problem:

var substringMatcher = function(strs) {
      return function findMatches(q, cb) {
        var matches, substringRegex;

        // an array that will be populated with substring matches
        matches = [];

        // regex used to determine if a string contains the substring `q`
        substrRegex = new RegExp(q, 'i');

        // iterate through the pool of strings and for any string that
        // contains the substring 'q', add it to the 'matches' array
        $.each(strs, function(i, str) {
          if (substrRegex.test(str)) {
            matches.push(str);
          }
        });
        cb(matches);
      };
    };
1

There are 1 answers

1
Jaromanda X On

Using regex will be painful because of all the "special" characters like ( [ etc

your code seems to be simple enough to not use RegExp anyway - indexOf should do the trick

var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
        q = q.toLowerCase();
        var matches = strs.filter(function(str) {
            return str.toLowerCase().indexOf(q) >= 0; 
        });
        cb(matches);
    };
};

Yes, ES2015+ has String#includes method which makes more sense to use - but then why not use ALL the benefits of ES2015+

const substringMatcher = strs => (q, cb) => {
    q = q.toLowerCase();
    cb(strs.filter(str => str.toLowerCase().includes(q))); 
};

or the less efficient (toLowerCase called more often than needed, but code is sexier

const substringMatcher = strs => (q, cb) => cb(strs.filter(str => str.toLowerCase().includes(q.toLowerCase())));