How can I use regex to replace everything except certain words in a string using Javascript

Imagine you have a line like this: "This is a sentence with words."

I have an array of words like $wordList = ["sentence", "words"];

I want to highlight words that are not on the list. This means that I need to find and replace everything else, and I cannot figure out how to do it (if possible) with RegEx.

If I want to combine words, I can do something like:

text = text.replace(/(sentence|words)\b/g, '<mark>$&</mark>');

(which will wrap matching words in "mark" tags and, assuming I have css for <mark>, highlight them), which works fine. But I need the opposite! I need to basically select the entire line and then exclude the listed words. I tried /^((?!sentence|words)*)*$/gm, but it gives me a strange problem of infinity, because I think it is too open.

Accepting this initial proposal, I would hope that in the end it will turn out "<mark> This is a </mark> sentence <mark> with some </mark> words."

Basically a wrapping (through replacement) of everything except the words listed.

The closest I can get is something like /^(?!sentence|words).*\b/igmthat will successfully execute it if the line starts with one of the words (ignoring the whole line).

So, we summarize: 1) Take the line 2) Take the list of words 3) Replace everything in the line except the list of words.

? (jQuery - , JS jQuery ).

+4
4

.
.
( )

var wordList = ["sentence", "words"];

// join the array into a string using '|'.  
var str = wordList.join('|');
// finalize the string with a negative assertion
str = '\\W*(?:\\b(?!(?:' + str + ')\\b)\\w+\\W*|\\W+)+';

//create a regex from the string
var Rx = new RegExp( str, 'g' );
console.log( Rx ); 

var text = "%%%555This is a sentence with words, but not sentences ?!??!!...";
text = text.replace( Rx, '<mark>$&</mark>');

console.log( text );
Hide result

/\W*(?:\b(?!(?:sentence|words)\b)\w+\W*|\W+)+/g
<mark>%%%555This is a </mark>sentence<mark> with </mark>words<mark>, but not sentences ?!??!!...</mark>

, . ,
. .

var wordList = ["sentence", "words", "won't"];

// join the array into a string using '|'.  
var str = wordList.join('|');
str = '([\\S\\s]*?)(\\b(?:' + str + ')\\b|$)';

//create a regex from the string
var Rx = new RegExp( str, 'g' );
console.log( Rx ); 

var text = "%%%555This is a sentence with words, but won't be sentences ?!??!!...";

// Use a callback to insert the 'mark'
text = text.replace(
        Rx,
        function(match, p1,p2)
        {
           var retStr = '';
           if ( p1.length > 0 )
              retStr = '<mark>' + p1 + '</mark>';
           return retStr + p2;
        }
      );

console.log( text );
Hide result

/([\S\s]*?)(\b(?:sentence|words|won't)\b|$)/g
<mark>%%%555This is a </mark>sentence<mark> with </mark>words<mark>, but 
</mark>won't<mark> be sentences ?!??!!...</mark>
+5

, / . , , , , , :

var text = "This is a sentence with words.";

text = "<mark>" + text.replace(/\b(sentence|words)\b/g, '</mark>$&<mark>') + "</mark>";

// If empty tags bother you, you can add:
text = text.replace(/<mark><\/mark>/g, "");

console.log(text);
Hide result

- , ( ) . , , .

X , Y , /<mark><\/mark>/g :

// Reserve memory for the longest string
const s = '<mark></mark>' + '<mark>x</mark>'.repeat(2000);
    regex = /<mark><\/mark>/g,
    millisecs = {};
// Collect timings for several string sizes:
for (let size = 100; size < 25000; size+=100) {
	millisecs[size] = test(15, 8, _ => s.substr(0, size).replace(regex, ''));
}
// Show results in a chart:
chartFunction(canvas, millisecs, "len", "ms");

// Utilities
function test(countPerRun, runs, f) {
    let fastest = Infinity;
    for (let run = 0; run < runs; run++) {
        const started = performance.now();
        for (let i = 0; i < countPerRun; i++) f();
        // Keep the duration of the fastest run:
        fastest = Math.min(fastest, (performance.now() - started) / countPerRun);
    }
    return fastest;
}

function chartFunction(canvas, y, labelX, labelY) {
    const ctx = canvas.getContext('2d'),
        axisPix = [40, 20],
        largeY = Object.values(y).sort( (a, b) => b - a )[
                    Math.floor(Object.keys(y).length / 10)
                ] * 1.3; // add 30% to value at the 90th percentile 
        max = [+Object.keys(y).pop(), largeY],
        coeff = [(canvas.width-axisPix[0]) / max[0], (canvas.height-axisPix[1]) / max[1]],
        textAlignPix = [-8, -13];
    ctx.translate(axisPix[0], canvas.height-axisPix[1]);
    text(labelY + "/" + labelX, [-5, -13], [1, 1], false, 2);
    // Draw axis lines
    for (let dim = 0; dim < 2; dim++) {
        const c = coeff[dim], world = [c, 1];
        let interval = 10**Math.floor(Math.log10(60 / c));
        while (interval * c < 30) interval *= 2;
        if (interval * c > 60) interval /= 2;
        let decimals = ((interval+'').split('.')[1] || '').length;
        line([[0, 0], [max[dim], 0]], world, dim);
        for (let x = 0; x <= max[dim]; x += interval) {
            line([[x, 0], [x, -5]], world, dim);
            text(x.toFixed(decimals), [x, textAlignPix[1-dim]], world, dim, dim+1);
        }
    }
    // Draw function
    line(Object.entries(y), coeff);

    function translate(coordinates, world, swap) {
        return coordinates.map( p => {
            p = [p[0] * world[0], p[1] * world[1]];
            return swap ? p.reverse() : p;
        });
    }
    
    function line(coordinates, world, swap) {
        coordinates = translate(coordinates, world, swap);
        ctx.beginPath();
        ctx.moveTo(coordinates[0][0], -coordinates[0][1]);
        for (const [x, y] of coordinates.slice(1)) ctx.lineTo(x, -y);
        ctx.stroke();
    }

    function text(s, p, world, swap, align) { // align: 0=left,1=center,2=right
        const [[x, y]] = translate([p], world, swap);
        ctx.font = '9px courier';
        ctx.fillText(s, x - 2.5*align*s.length, 2.5-y);
    }
}
<canvas id="canvas" width="600" height="200"></canvas>
Hide result

( 100 ) 15 . 8 , ​​ . 25 25 000 ( <mark>). , -)

(- ), . , , .

:

if (text.substr(6, 7) === '</mark>') text = text.substr(13);
if (text.substr(-13, 6) === '<mark>') text = text.substr(0, text.length-13);

- , JavaScript (), .

, , .

+3

, , .

let s1 = "This is a sentence with words.";
let wordList = ["sentence", "words"];

let reg = new RegExp("([\\s\\S]*?)(" + wordList.join("|") + ")", "g");

console.log(s1.replace(reg, "<mark>$1</mark>$2"))
Hide result
+1

: , .

text = `<mark>${text.replace(/\b(sentence|words)\b/g, '</mark>$&<mark>')}</mark>`;

, . . , :

//var text = "This is a sentence with words.";
//var wordlist = ["sentence", "words"];
var result = "";
var marked = false;
var nextIndex = 0;

while (nextIndex != -1) {
    var endIndex = text.indexOf(" ", nextIndex + 1);
    var substring = text.slice(nextIndex, endIndex == -1 ? text.length : endIndex);
    var contains = wordlist.some(word => substring.includes(word));
    if (!contains && !marked) {
        result += "<mark>";
        marked = true;
    }
    if (contains && marked) {
        result += "</mark>";
        marked = false;
    }
    result += substring;
    nextIndex = endIndex;
}

if (marked) {
    result += "</mark>";
}
text = result;
+1

Source: https://habr.com/ru/post/1684000/


All Articles