Using a combination of look-arounds and tag omission for advanced parsing

I am trying to identify text that is not part of another word (which I have working successfully), but I also want to ensure that the text is not inside an <a> tag.

"Java <li>Javascript</li> <a href="">Some Java here</a> more java"

var regex2 = new RegExp(`(?<![a-z])Java(?![a-z])`, "gi");

text = text.replace(regex2, '++JavaUpdated++');

The code snippet above works fine, however when I tried to include additional lookarounds as shown below, it didn't work as expected:

var regex2 = new RegExp(`(?<![a-z])(?<!<a.*)Java(?!.*<\/a>)(?![a-z])`, "gi");

Answer №1

Avoid using regular expressions to parse HTML, but in case you really need to...

If you are determined to use regex, here is an example of a regex expression that can be used if your browser supports lookbehinds:

(?<![^\s])JavaScript(?![^\s])(?!(.(?!<a))*<\/a>)

Regex Example

This regex pattern checks for whitespace before and after the word JavaScript, while also ensuring it is not within tags using negative lookahead.

I see that your original regex includes a negative lookbehind, which may not be supported in JavaScript versions prior to 2018. Make sure to check browser compatibility if you decide to use this feature. Lookbehinds are specifically available in browsers that adhere to the ECMA2018 standard.

If you prefer not to rely on negative lookbehinds, an alternative approach could be:

(?:\s$|^)JavaScript(?![^\s])(?!(.(?!<a))*<\/a>)

Alternative Regex Demo

In this scenario, the regex specifies not to match JavaScript if it is preceded by any character other than whitespace or if it is part of a word.

Answer №2

To tackle this issue, you can start by dividing the string based on <a> tags. Then, process each segment of the string individually. Replace occurrences of Java with ++JavaUpdated++ only if the segment does not commence with <a:

const str = 'Java <li>Javascript</li> <a href="">Some Java here</a> more java';

let newstr = str.split(/(<a.*?<\/a>)/)
                .map(v => (v.slice(0, 2) == '<a') ? v : v.replace(/\bJava\b/i, '++JavaUpdated++'))
                .join();

console.log(newstr);

Answer №3

When handling cases where text may not break into separate nodes, the following method can be utilized to address this scenario. The strategy involves traversing through the Text nodes within the DOM while disregarding any anchor tags that are encountered along the way.

// Utilizing RegExp as a literal
const re = /(?<![a-z])Java(?![a-z])/gi

const walkTextNodesIgnoringAnchors = (el, fn) =>
  el.childNodes.forEach(child => {
    // Exclude anchors
    if (child.nodeName === 'A') return
    
    // For Text nodes, execute the provided function
    else if (child.nodeName === '#text') fn(child)
    
    // Otherwise, recursively traverse deeper
    else walkTextNodes(child, fn)
  })

const textEl = document.querySelector('.js-text')

walkTextNodesIgnoringAnchors(textEl, (textNode) => {
  textNode.textContent = textNode.textContent.replace(re, '++JavaUpdated++')
})
<div class="js-text">Java Javascript <a href="">Some Java here</a> more java</div>

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

Connecting two COTURN servers for seamless communication

Currently, I have a total of 5 webRTC peers connected through the COTURN server (turnServer1). These peers are all behind symmetric NAT, requiring the use of the TURN server to establish connections. However, due to the media streams with audio and video b ...

Using the array.prototype.map method on props in React.js results in an array that is devoid

Recently, I've started exploring the world of React and encountered a problem while attempting to convert the value of props into a JSX element using array.prototype.map(). You can learn more about this method at this link. Here is a snippet of a Rea ...

Combining various components within an inactive element tag using Vue

I am working on creating expandable rows for a table element using this HTML code snippet. The current approach involves alternating between parent rows and multiple rows within tbody elements. <tbody class="js-table-sections-header">Parent row</ ...

"Effortlessly move files with Filedrop HTML 5 and Jquery drag-and-drop feature

I am trying to implement a drag and drop file feature on my webpage, but for some reason, it's not working as expected. The drop zone is supposed to change its background color when I drag a file onto it, but that functionality doesn't seem to be ...

JavaScript does not reflect updates made to the ASP.Net session

After clicking the button, I trigger the JavaScript to retrieve the session information. However, I am encountering an issue where the value of the session is not being updated. alert('<%= Session["file"]%>'); ...

Discover the process of dynamically importing JavaScript libraries, modules, and non-component elements within a Next.js

Lately, I have been utilizing Next.js and mastering its dynamic import feature for importing components with named exports. However, I recently encountered a particular npm package that functions only on the client-side (requires window) and has a substant ...

Stay updated with the complex query change feed in RethinkDB

When faced with a query like the following: r.db('universe') .table('Star') .getAll( r.db('universe').table('Ship').get(idShip)('idCurrentGalaxy'), {index: 'idGalaxy'} ) .changes ...

Converting JSON to a list using JavaScript

As a beginner in JavaScript, I apologize for asking possibly a redundant question. Can someone guide me on the most effective way to parse json? I am specifically interested in extracting a list of strings under the name Maktg: { "d":{ "res ...

Fetching dynamic information via AJAX for a jQuery tooltip

I have successfully loaded content via AJAX, including a UL element with li items that each have tooltips. Now I want to load tooltip content via AJAX for each individual li item. How can I achieve this? Currently, I am making an AJAX call to load the li ...

The like button seems to be malfunctioning and I'm not sure what the issue is

I've added the ability for users to like my posts, but it's not working as intended. Here's the code snippet I used: models.py class Post(models.Model): title = models.CharField(max_length=100) content = models.TextField(blank=Tru ...

Is there a way to convert arrow functions in vue files through transpilation?

I have developed a Vue application that needs to function properly in an ES5 browser (specifically iOS 9). One issue I've encountered is that some of the functions within the Vue components are being transformed into Arrow functions: ()=>, which i ...

Utilizing AngularJS for Converting Date Formats from JSON and HTML Elements

So I have this controller set up. function TestCtrl($scope) { var contentFromJson = 'Hi! this is <b>Bold</b> and <i>Italic</i>'; var dateFromJson = '/Date(1394526738123)/'; $scope.Date = dateFromJso ...

A script error occurs exclusively on dynamic routing in a static web page generated by NUXT

Currently working on a Nuxt.js website and encountering an issue. Initially, nuxt.config.js was set up as below to enable a headless CMS. export default { target: "static", ssr: true, generate: { async routes() { const pages = awa ...

Embracing PWAs with subdomains – seamless installation

One of my Progressive Web Applications (PWA) called app A contains a link to another app, app B. Initially, I hosted both apps on the same subdomain (for example: ) and everything worked perfectly - installing app A also installed app B. However, when I a ...

Personalized animated Reactflow Connection Lines

My goal is to develop a personalized animated connection lines in reactflow, rather than using the default dashed line that appears when the animated: true prop is applied. I am aware that we can customize the styling by using the following code snippet: ...

Delete an entry from the localStorage

I am attempting to create a basic To-Do list using jQuery, but I have encountered an issue. This is my first time utilizing localStorage. After setting up the structure for my To-Do list, I wanted the items to remain visible when I refresh the page. Initia ...

What sets Angular 2 apart when it comes to utilizing [ngStyle] versus [style.attribute]?

When using Angular 2, what distinguishes the following 2 options for passing a variable value to a style? Are there advantages and disadvantages, or is it simply a matter of personal preference, or is one more adaptable/meant for specific purposes? Option ...

When utilizing res.redirect in Express, an error is triggered stating "Uncaught SyntaxError: Unexpected token <""

Utilizing Node.js, Express, Socket.io, firebase admin+auth, and Handlebars. An error Uncaught SyntaxError: Unexpected token < keeps popping up. Whenever I use res.redirect('/login');, I encounter the error. It disappears when I remove res.re ...

Converting a JavaScript array into JSON using PHP

After analyzing the text, I was trying to figure out how to convert it into json format using php's json_decode function. Unfortunately, when I used json_decode on this text, it returned a syntax error. $arr = json_decode($str, true); {1: {name: &ap ...

Incorporating object into main function of VueJS root component

I have integrated VueJS into my HTML template for an application. When a button is clicked, it passes the object of a component to its root in the following manner: <button v-on:click="$root.savePlan(dataObj)"></button> The dataObj is passe ...