user1141649 user1141649 - 3 months ago 7
Javascript Question

How to force regexp not to split matches in Javascript?

I am having this code:

id = selectors[s].match(new RegExp( "(^|\\s" + regexes.ids + "\\s|$)", 'gm'));


The resulting regexp:

/(^|\s(#sidebar-right-1|#BlogArchive1|#ArchiveList|#BlogArchive1_ArchiveList|#PopularPosts)\s|$)/gm


The problem is that when selectors[s] does contain the id I am looking for, it returns match like [ "", "" ] which is not what I want. Can you tell me how to force it not to split the result? I mean - when I am looking for
(wordA(wordB)wordC)
and wordB is not in the string, then no result should be returned or only one result with null. If all word B is present but wordA or wordB is missing, it should also return null or one element with null.

Is it possible to do? I was used to do this in PHP but Javascript algorithms seems to be slightly different.

Edit:

I also tried

/^|s(#sidebar-right-1|#BlogArchive1|#ArchiveList|#BlogArchive1_ArchiveList|#PopularPosts)s|$|{/gm
before

Answer

There're several problems:

  • first, when you want to figure a backslash in a quoted string for the RegExp constructor, you need to escape it.
  • you want to concatenate an alternation with parts to delimit the item. In this case, to put the "boundaries" in factor with the alternation, you need to put the alternation in a group.
  • to finish, Javascript supports lookaheads, so you can replace (\s|$) with (?!\S). Doing that avoids to create a group and to test an alternation for nothing, but the main advantage is that your pattern is able to match several occurances separated by only one white-space.

result:

new RegExp("(^|\\s)(" + regexes.ids + ")(?!\\S)"); 

Other thing, all your items start with a #, it's better put it in factor to fail faster (instead of testing each item at positions that don't have a sharp):

new RegExp("(^|\\s)(#(?:" + regexes_without_sharp.ids + "))(?!\\S)");