Ed Die
Ed Die

Reputation: 227

javascript str.replace color the word preceding a string

In a csv.file a column 'col2' row contains a string:

"unserer {m}, unsere {p} and {f}, unseres {n}"

it is appended dynamically

d3.select("#element").html(d.col2)

based on the content of {m|f|n} I would like to change the background color of the text.

I am looking with a regex statement like this:

/.*(\w+)\s\{f\}.*/ 

where I want to replace the \w+ with

'<span style=background-color:red|yellow|green;>$1</span>

and I need this for three use case being {m}, {f}, {n}, which each are supposed to have their own text color. So

 d3.select("#sentence").html(d.col2).html(function(d) {
   if ( this.match("{m}"){ 
        this.replace(/.*(\w+)\s\{m\}/gi, "<span  style=color:red;>" + $1"</span>");
 } if ( this.match("{f}") {
       this.replace(/.*(\w+)\s\{f\}/gi, "<span style=color:yellow;>" + $1"</span>");
 } else {
 this.replace(/.*(\w+)\s\{n\}/gi, "<span style=color:green;>" + $1"</span>");
 }
 };)

This code is rather pseudocode of what I would like to do; it is not working and I am not sure that it can be done this way.

Upvotes: 0

Views: 114

Answers (2)

Carsten Massmann
Carsten Massmann

Reputation: 28196

No need to explain the German to me - I am German. ;-)

Here is my version of a RegExp, that maybe treats the genders and plurals a bit better:

var r=/(^|,)\s*(.*?)(?=\s+\{([fmn])\})/g;
s.replace(r,'$1<span class="$3">$2</span>');

For simplicity I assigned the spans the classes m,n and f.

My RegExp looks for anything between a valid gender tag ({m},{f} or {n}) and the start of the string or a , (comma) and considers that to be the string that needs coloring.

The result of this would be

'<span class="m">unserer</span> {m}<span class="f">unsere {p} and</span> {f}<span class="n">unseres</span> {n}'

The classes of course need to be given suitable colors in your CSS.

update

As you know, good things can always be improved, so here is a version that will not color the {p} tags (or anything starting with '{'):

s.replace(/(^|,)\s*([^{]+)(?=.*?\{([fmn])\})/g,'$1<span class="$3">$2</span>')

This will get you

'<span class="m">unserer </span>{m},<span class="f">unsere </span>{p} and {f},<span class="n">unser </span>{n}'

Upvotes: 2

Paul S.
Paul S.

Reputation: 66324

You can use a function as the replacor in str.replace and you can use a lookahead in your RegExp

var str = "unserer {m}, unsere {p} and {f}, unseres {n}";

var d = {
        m: 'red',
        f: 'yellow',
        n: 'green'
    },
    re = /(\w+)(?=\s+\{([^}]+)\})/g;
str = str.replace(
    re,
    function ($0, $1, $2) {
        if ($2 in d)
            return '<span style="color:' + d[$2] + ';">' + $1 + '</span>';
        return $0;
    }
);
// '<span style="color:red;">unserer</span> {m}, unsere {p} <span style="color:yellow;">and</span> {f}, <span style="color:green;">unseres</span> {n}'

Upvotes: 1

Related Questions