Balaclava
Balaclava

Reputation: 129

Alternative for negative lookbehind regex not working in Firefox

It is not the first question about this issue but I couldn't find a solution for my case.

I am trying to select a character or group of characters only when these are not preceded by an alphanumeric character. Example:

This is an example (a simple sentence from https://aniceone.com)

I need to match the letter "a" from "an", "(a" and "https://aniceone.com".

The following expression works in Chrome but in Firefox, so I need an alternative.

new RegExp(`((?<!\\w)${query})`, "gi")

Note that the content to match arrives dynamically. Here you can see the whole function (FYI, I am trying to highlight text from a search query):

const getHighlightedText = (item, query) => {
  const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  const parts = item.split(new RegExp(`((?<!\\w)${escapedQuery})`, "gi"));
  return (
    <React.Fragment>
      {parts.map((part, ind) => (
        <span
          key={ind}
          style={
            part.toLowerCase() === query.toLowerCase()
              ? { fontWeight: "bold", backgroundColor: "#eeff00" }
              : {}
          }
        >
          {part}
        </span>
      ))}
    </React.Fragment>
  );
};

Upvotes: 1

Views: 104

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626926

You may find all matches of new RegExp(`(\\W|^)(${escapedQuery})`, "gi"), check if Group 1 matched, and populate the final chunk array by appending substrings of the original string at appropriate indices only.

See an example:

function splitSpecial(s, query) {
  var current=0, res=[], rx = new RegExp("(\\W|^)(" + query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ")", "gi");
  while (m=rx.exec(s)) {
    res.push(s.substring(current, m.index + (m[1] ? 1 : 0)));
    res.push(m[2]);
    current = m.index + m[0].length;
  }
  if (current < s.length) {
    res.push(s.substr(current));
  }
  return res;
}

console.log(splitSpecial("@abc abc@abc @abc,@abc!@abc", "@abc"));
// => ["", "@abc", " abc@abc ", "@abc", ",", "@abc", "!", "@abc" ]

Upvotes: 1

Related Questions