React JS - 替换匹配的字符串并将字符串添加到下一个匹配的字符串

时间:2018-03-20 07:34:10

标签: javascript reactjs

对不起 对于令人困惑/误导的标题,我不确定如何说出这个。

基本上,我正在从CS:GO服务器中提取玩家数据,重要的是玩家等级给予我作为字符串,例如{default}[{pink}Master{default}]

花括号内的游戏内颜色会被替换为十六进制值,但对于我的反应应用程序,我试图替换它们,所以它' 像< span style = "color: #fff;" > [ < /span><span style="color: #ffb6c1;">Master</span > <span style="color: #fff;">]</span>     或[大师]主人将是粉红色的阴影     我可以替换{         颜色     }     使用开口跨度标签很容易,但我不知道如何到达跨度应该结束的位置。

尝试过这样的事情

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来自https://www.npmjs.com/package/react-string-replace

我的想法是获得第一个匹配的索引{color}然后获得下一个匹配的索引{并获取介于这两个之间的任何内容。

显然不能正常工作,但任何帮助都会很棒。

1 个答案:

答案 0 :(得分:1)

我会使用React的dangerouslySetInnerHTML。它可能......好吧,危险,但它有它的用途。

对于实际替换,.replace()应该足够了,并且希望比.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>
*/

替换颜色字符串({pink}变为<span style='color: #ffb6c1'>)将类似。

或者,你可以只使用一个替换品并在某种配置对象中查找颜色,如下面的代码片段所示:

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>

无论您使用何种方法,在实际应用中,您都需要清理字符串以避免XSS 漏洞!例如。在将任何HTML标记传递给formatRank函数之前将其删除,以确保没有人可以在播放器名称中隐藏<script>