JS React:用字符串中的组件替换正则表达式

JS React: replacing regex with component in a string

给定一个字符串,格式为:

'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.'

我想使用 RegEx 拆分它并用一些 React 组件替换巧合。该字符串将具有组件类型 (FaIcon) 和其中的道具,例如图标的名称 (Upload)。

这个 objective 是为了能够在翻译后的字符串中使用 React 组件,预期的 return 值将是 类似于:

[
  'This is a string with some ',
  <FaIcon iconName="Upload" />,
  ' in it as ',
  <FaIcon iconName="Download" />,
  ' these two.'
]

方法

目前,我有一个方法 return 是字符串或数组。这与 React 渲染方法兼容,因为如果我们 return 一个数组,它将能够渲染该数组上的任何组件。

因为我将使用它来翻译一些字符串,所以我创建了这个自定义挂钩:

const useCustomTranslation = () => {
  const { t } = useTranslation();

  const tlt = (...args) => {
    // const str = t(...args);
    const testStr =
      'This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.';
    const reg = /(?<=::FaIcon)(.*?)(?=::)/g;

    const preStrAr = testStr.split(reg);
    console.log(preStrAr);
  };

  return { tlt };
};

问题

目前,此方法正在记录此:

[
    "This is a string with some ::FaIcon",
    "Upload",
    ":: icons in it as ::FaIcon",
    "Download",
    ":: these two."
]

如您所见,它不包括 ::FaIcon 和最后的 ::,因为我无法找到正确的正则表达式来这样做。但是 即使我到了那个点,我觉得我应该 重新遍历数组 以用正确的方式替换字符串组件,再次使用 Regex 查看数组项是否匹配正确的格式。

我觉得这在某种程度上过于复杂,我认为必须有一种更简洁、更简单的方法来获得它(如果我错了请纠正我,这是唯一的方法)。

有什么方法可以使用正则表达式拆分字符串,使用匹配组的一部分将字符串替换为使用该匹配字符串的另一个内容?

也许你是故意这样做的?

/::FaIcon(.*?)::/不看

const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/::FaIcon(.*?)::/g,function(_,match) {
  return  `<FaIcon iconName="${match}" />`
})
console.log(newText)
要制作一个数组,你可以这样做

const str = `This is a string with some ::FaIconUpload:: icons in it as ::FaIconDownload:: these two.`
const newText = str.replace(/\s?::FaIcon(.*?)::\s?/g,function(_,match) {
  return  `::<FaIcon iconName="${match}" />::`
}).split("::")
console.log(newText)

最后,我(遗憾地)使用了 re-iteration 方法,因为这是我认为它可行的唯一方法。感谢 @mplungjan 他的第一个回答,它给了我让它工作的提示:

export const replaceIconInStr = (str) => {
  // Matches the whole icon component pattern 
  const regComponent = /(::FaIcon.*?::)/g;
  // Matches just the component prop we need
  const regIconName = /::FaIcon(.*?)::/g;

  // Split the string by the component pattern
  const splittedStr = str.split(regComponent);

  // If there are any matches
  if (splittedStr.length) {
    // Match the elements in the array and get the prop to replace it by the real component
    return splittedStr.map((el) => {
      const matched = regIconName.exec(el)?.[1];
      if (matched) {
        return <FaIcon iconName={matched} />;
      }

      return el;
    });
  }

  // If there is no pattern matching, return the original string
  return str;
};