2

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);
      };
    };
jason
  • 63
  • 1
  • 7
  • `(` and many other characters have "special" meaning in a RegExp - see [documentation](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Special_characters_meaning_in_regular_expressions) – Jaromanda X Dec 14 '16 at 12:30
  • I know, so any suggestion how to solve this? – jason Dec 14 '16 at 12:43
  • if you know about the special characters in RegExp expressions, then you know what the special character \ does – Jaromanda X Dec 14 '16 at 12:46
  • I'm trying replace ( with \ ( but it doesn't help – jason Dec 14 '16 at 12:50
  • you have to understand that in a string literal "like this" ... \ also has a special "meaning" ... so to put it in s string that is used to create a RegExp, you need to use TWO ... so, you would need `q` in your code to be "\\\(" – Jaromanda X Dec 14 '16 at 12:58
  • Of course, you'll need to escape more than just `(` ... sometimes it's just easier to use indexOf iteratively, using the seldom used second argument to indexOf - though in this case you wouldn't even need to use indexOf more than once per `strs` – Jaromanda X Dec 14 '16 at 13:00
  • Replace with 2 slash help me, thanks! Can you please write an answer and I'll accept your answer? – jason Dec 14 '16 at 14:33
  • I think you need to escape your string before you pass it to RegExp. See this one - https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript – Piyush Balapure Oct 22 '18 at 10:44

1 Answers1

3

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()))); 
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Thank you for your answer, but I've tried to use any of these and have an error: (index):540 Uncaught TypeError: strs.filter is not a function – jason Dec 14 '16 at 14:27