Reputation: 37
Sorry for the confusing / misleading title, wasn 't really sure how to word this one.
Basically, I am pulling players data from a CS:GO server, importantly the players rank which is given to me as a string such as {default}[{pink}Master{default}]
In-game colours inside of the curly braces get replaced with hex values, however for my react app I am trying to replace them so it'
s like< span style = "color: #fff;" > [ < /span><span style="color: #ffb6c1;">Master</span > <span style="color: #fff;">]</span>
or[Master] where master would be some pink shade
I can replace the {
colours
}
with the opening span tag easily, however I 'm not sure how to get where the span should end.
Tried something like this
const replaceColours = function(str) {
const original = str;
let index;
let indexNext;
let strOut;
let colour;
if (str.indexOf("{default}") !== -1) {
index = str.indexOf("{default}");
// console.log(index);
strOut = str.substr(index);
strOut = strOut.replace("{default}", "");
// console.log(strOut);
indexNext = strOut.indexOf("{");
if (indexNext !== -1) {
strOut = strOut.substr(0, indexNext);
}
// console.log(strOut);
colour = reactStringReplace(str, "{default}", (match, i) => (
<span key={i} style={{color: '#fff'}}></span>
));
}
console.log(colour);
return colour;
}
reactStringReplace is from https://www.npmjs.com/package/react-string-replace
My idea was to get the index of the first match {colour} then the index of the next { and get whatever is in-between those two.
Obviously doesn't work properly, but any help would be great.
Upvotes: 0
Views: 7918
Reputation: 3234
I would use React's dangerouslySetInnerHTML
for this. It can be… well, dangerous, but it has it's uses.
For the actual replacement, .replace()
should be sufficient, and hopefully easier than .indexOf
:
str.replace(
/{default}([^{$]*)/g,
// '[^{$]*' means 'more than 0 characters except { or end-of-string'
'<span style="color: #fff;">$1</span>'
// $1 is a 'capture group' - everything between ( and ) in the regex above
)
/*
so…
{default}[{pink}Peter{default}]
…gets replaced to:
<span style="color: #fff;">[</span>{pink}Peter<span style="color: #fff;">]</span>
*/
Replacement of color strings ({pink}
becomes <span style='color: #ffb6c1'>
) would be similar.
Or, you can use just one replacement and look for colors in some sort of a config object, like in this snippet below:
const colors = {
default: "#fff",
pink: "#f44283",
blue: "#41d9f4",
green: "#4cf441",
yellow: "#f4d041"
};
const formatRank = rank =>
rank
.replace(
// https://regex101.com/r/AbXrhg/1
/{([^}]+)}([^{$]*)/g,
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter
(match, color, content) =>
`<span style='color: ${colors[color]};'>${content}</span>`
);
const Player = ({ rank }) => (
<div
className="player"
dangerouslySetInnerHTML={{
__html: formatRank(rank)
}}
/>
);
const app = (
<div>
<Player rank="{default}[{pink}Peter{default}]" />
<Player rank="{default}[{blue}Mary{default}] {green}kicks some asses" />
<Player rank="{default}[{blue}John {pink}Paul {yellow}II.{default}]" />
<Player rank="[{green}Fido{default}] {blue}i'm actually a {default}dog {yellow}🐶" />
</div>
);
ReactDOM.render(app, document.querySelector("#app"));
body {
background: #444;
font: 12pt/1.5em monospace;
padding: 0;
margin: 0;
}
.player {
background: #333;
color: #fff;
padding: 0.25em;
margin: 0.5em 0.5em 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Whatever method you use, in an actual app, you need to sanitize the strings to avoid XSS vulnerabilities! Eg. strip any HTML tags before passing it to formatRank
function to make sure that nobody can sneak a <script>
in player's name.
Upvotes: 1