Prevent regex special characters in JavaScript while preserving the original string for keyword matching

As I develop my web page, I encountered an issue while trying to highlight text based on user input in the search box. My search algorithm matches each space-separated keyword, but ran into problems when including brackets in the search term. This caused a SyntaxError: Invalid regular expression due to unterminated groups being interpreted by the regex. Despite attempts to escape the brackets and other characters, the highlighting feature stopped functioning properly.

Visit this link for more information

highlight (str) {
    // The line below works, but it doesn't allow highlighting multiple disconnected keywords
    // var replacedStr = (this.search || '').replace(/[-[\]{}()*+!<=:?.\\^$|#\s,]/g, '\\$&')

    // you can comment this line and uncomment above to see a different but not perfect option
    var replacedStr = (this.search || '').replace(/ /g, '|')
    return str.replace(new RegExp(replacedStr, 'gi'), match => {
      return '<span class="font-weight-bold">' + match + '</span>'
    })
}

I attempted to escape the brackets as shown in the commented line, but it resulted in the function failing to properly highlight all keywords within the text :/

Any suggestions or ideas to address this issue?

Answer №1

If you want to search for and highlight non-whitespace chunks, be sure to escape each one beforehand. Additionally, there is no need to utilize a callback inside replace when replacing with the entire match, as you can simply use the $& backreference.

Take a look at the JS update:

vm = new Vue({
    el: "#app",
    data() {
        return {
            search: null,
            message: 'Search this text for matches (check the bracketed area too)'
        };
    },
    computed: {},
    methods: {
        highlight (str) {
          var replacedStr = (this.search || '').trim().split(/\s+/).map(x => x.replace(/[-[\]{}()*+!<=:?.\\^$|#\s,]/g, '\\$&')).join("|");
          return str.replace(new RegExp(replacedStr, 'gi'), 
            '<span class="teal--text text--darken-1 font-weight-bold">$&</span>');
        }
    }
});

In the following:

  • .trim().split(/\s+/).map(x => x.replace(/[-[\]{}()*+!<=:?.\\^$|#\s,]/g, '\\$&')).join("|")
    - trims the input string using trim(), then splits all non-whitespace chunks with .split(/\s+/), escapes these chunks with
    .map(x => x.replace(/[-[\]{}()*+!<=:?.\\^$|#\s,]/g, '\\$&'))
    , and finally creates a regex pattern using .join("|").
  • Within the string replacement pattern
    '<span class="teal--text text--darken-1 font-weight-bold">$&</span>'
    , $& represents the whole match value.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Material UI Rating Component is malfunctioning and showing an incorrect value

I'm currently working on a component loop that takes in async data. Everything is rendering properly except for the first component, where the Rating component isn't displaying its value correctly (it just shows 0 stars). Here's the code: & ...

Tips for exporting 3D objects from 3ds Max Studio for optimal use in Three.js

I am facing an issue with loading a 3D object that I created in 3D Studio Max! When I export it as a .obj file (which generates two files, .obj and .mtl), I have tried using OBJMTLLOADET(), MTLLOADER(), and OBJLOADER() but none of them seem to work. Other ...

Finding the Perfect Placement for an Element in Relation to its Companion

Is there a way to achieve an effect similar to Position Relative in CSS using jQuery? I have developed a tooltip that I want to attach to various objects like textboxes, checkboxes, and other text elements. My code looks something like this: <input i ...

Using Vue3 to Enable or Disable the Submit Button Based on Changes in Editable Form Content

Here is a practical example, demonstrating how to create an editable address form. The save button should remain disabled if the form remains unchanged, as there is no need to submit it. However, when a value changes, the save button should become enabled ...

What could be causing my HTML elements to shift position based on varying screen sizes or zoom levels?

Does anyone else experience their HTML and CSS elements shifting around based on the screen size or zoom level? I have screenshots illustrating this issue. Here is how it currently appears And here is how it's supposed to look ...

Massive HTML Table Containing Rows upon Rows

Currently, I have a server that can provide me with a list of objects in json format, and my goal is to showcase them in a table on the client side. Initially, I thought about dynamically modifying the DOM after receiving data from the server. Building th ...

Having trouble with installing Angular JS on my computer

On my machine, I have successfully installed node.js version v0.12.0. However, when attempting to run sudo npm install, I encountered the following errors: npm ERR! install Couldn't read dependencies npm ERR! Darwin 14.0.0 npm ERR! argv "node" "/usr/ ...

What could be causing my controller to show {{message}} instead of the message that was set up in the configuration

<!DOCTYPE html> <html> <head> <script src="js/angular.js"></script> <script src="js/Script.js"></script> </head> <body ng-app="LoginPage" ng-controller = "LoginPageController"> <form ...

How do I access a specific child from an object/element retrieved by using the elementFromPoint() method in Javascript?

Is there a method to extract the child element from an element or object retrieved by the function elementFromPoint(x, y); Consider the following scenario: var elem = document.elementFromPoint(x, y); Let's assume that the element returned and saved ...

The updateItem function in the JSGrid controller was not called

Currently, I am working on a project involving js-grid. However, I have encountered an issue where the updateitem function of the controller is not being invoked when attempting to update a column field. Additionally, the field resets to its old value wi ...

Tips for managing open and closed components within a React accordion and ensuring only the clicked component is opened

Unique Accordion component: const CustomAccordion = (props: AccordionProps) => { const { label, levels, activeId, id } = props const [isExpand, setIsExpand] = useState(false) const onPress = useEvent(() => { setIsExpand( ...

Discover the magic of Bootstrap 3.0 Popovers and Tooltips

I'm struggling with implementing the popover and tooltip features in Bootstrap. While I have successfully implemented drop downs and modals, the tooltips are not styled or positioned correctly as shown in the Bootstrap examples, and the popover featur ...

Struggling with Vue animations on displayed components

Vue 2.1.10 I have implemented a component in Vue that handles the process of sending email invitations. Users input an email address into a text field and hit a button, triggering a request to the server. The response from the server is stored in the invi ...

The object's key values were unexpectedly empty despite containing data

There's an issue with my object - it initially gets key values, but then suddenly loses them all. All the key values become empty and a message appears in the console for the object: "this value was evaluated upon first expanding. it may have ch ...

Node.js offers a simple and efficient way to retrieve screen resolution. By using

I am trying to retrieve the screen resolution using node.js, but the code snippets provided are not working as expected. var w = screen.width; var h = screen.height; The following code also did not work for me: var w = window.screen.width; var h = windo ...

How can I include a path prefix to globs provided to gulp.src?

Consider the contents of these two essential files: settings.json { "importFiles": [ "imports/data.js", "imports/functions.js", "imports/styles.css" ] } builder.js var build = require("builder"), combine = require("combine-files"), ...

Internet Explorer not triggering jQuery blur() or focusout() events

Having some issues with my form and event handling when the inputs lose focus. The code is working perfectly in every browser except for Internet Explorer. function formstyle() { var focus = 0; //comentario is the ID of the input $("#comenta ...

In what circumstances should one utilize either the "this" keyword or an event argument?

$("span").on("click",function(event){ event.stopImmediatePropagation(); }) $("span").on("click",function(event){ $(this).stopImmediatePropagation(); }) Can you explain the distinction between these two code snippets and why only one of them is ...

Exploring the Time Interval Between Sending GET and POST Requests in Node.js and Express

I'm currently in the process of creating a quiz platform with Node/Express. Is there a way to guarantee that users complete the quiz within a specific timeframe without utilizing client-side javascript? For example, if the quiz is set for 10 minutes, ...

Is it possible to change the text of a scrollspy dropdown to a default text when it is not actively tracking any items?

I am new to Vue and currently implementing Bootstrap Vue Scrollspy (view example here). My sticky dropdown is tracking all referenced content and updates with the current section in view. You can check out my code sample here. Is there a way to set the d ...