提取RichText
import React from "react";
const getRichTextPosition = (s: string, key: string) => {
const values: { from: number; to: number; tag: string }[] = [];
let searchStart = 0;
const tagLeft = `<${key}>`;
const tagRight = `</${key}>`;
let tagStart = s.indexOf(tagLeft, searchStart);
let tagEnd = s.indexOf(tagRight, searchStart);
while (tagStart > -1 && tagEnd > -1) {
searchStart = tagStart + tagLeft.length;
values.push({
from: searchStart,
to: tagEnd,
tag: key
});
searchStart = tagEnd + tagRight.length;
tagStart = s.indexOf(tagLeft, searchStart);
tagEnd = s.indexOf(tagRight, searchStart);
}
return values;
};
export default function App() {
const t = (
s: string,
richOptions?: Record<string, (value: string) => React.ReactNode>
) => {
if (richOptions) {
let isNested = false;
const results: React.ReactNode[] = [];
let positions: { from: number; to: number; tag: string }[] = [];
const optionKeys = Object.keys(richOptions);
if (optionKeys.length > 1) {
optionKeys.forEach((key: string) => {
positions = positions.concat(getRichTextPosition(s, key));
});
positions.sort((a, b) => a.from - b.from);
} else {
positions = getRichTextPosition(s, optionKeys[0]);
}
let start = 0;
positions.forEach((position) => {
if (start > position.from) {
isNested = true;
}
results.push(
s.substring(start, position.from - (position.tag.length + 2))
);
results.push(
richOptions[position.tag](s.substring(position.from, position.to))
);
start = position.to + (position.tag.length + 3);
});
results.push(s.substring(start));
if (isNested && process.env.NODE_ENV !== "production") {
throw new Error(`[Localization] - "${s}" includes nest tag`);
}
return results;
}
return s;
};
const str = "aaa<strong>你好张三</strong><t>,欢迎来到你好啊</t>ggggg<strong>这里武汉</strong>gggg";
const node = t(str, {
strong: (value: string) => (
<strong style={{ color: "red" }}>{value}</strong>
),
t: (value: string) => (
<strong style={{ color: "green" }}>{value}</strong>
)
});
return (
<div className="App">
{node}
</div>
);
}