javascript - 在javascript中将纯文本转换为超链接
问题描述
我有一个用例,我需要识别字符串中的电话号码并将它们转换为可点击的链接。目前使用外部库超出了范围。
这是我到目前为止所做的:
字符串:“这是我的电话号码 - 1234567890”我可以使用正则表达式模式提取 1234567890 作为电话号码。
我现在想用原始字符串替换它,所以这就是我所做的:
const string = "This is my phone number - 1234567890"
const number = "1234567890"
const newString = '<a href="#">' + number + '</a>'
number = number.replace(number, newString);
当我这样做时,我的输出不是以超链接的形式获取电话号码,而是如下所示:
This is my phone number - <a href="#">1234567890</a>
如果我创建不带引号的 newString,就像这样
const newString = <a href="#">number</a>
我的输出是这样的:
This is my phone number - [object Object]
如何使它成为可点击的链接?
解决方案
您需要替换以使用链接包装电话号码,然后用于dangerouslySetInnerHTML
添加到 React 组件。
注意:之所以调用它,是dangerouslySetInnerHTML
因为您对来自用户生成内容的 XSS 攻击敞开心扉。您应该先对字符串进行消毒。
const Linkify = ({ text, pattern, formatter }) => {
const __html = text.replace(pattern, formatter);
return <div dangerouslySetInnerHTML={{ __html }} />;
};
const text = 'This is my phone number - 1234567890';
const pattern = /\d+/g;
const formatter = str => `<a href="#${str}">${str}</a>`;
ReactDOM.render(
<Linkify text={text} pattern={pattern} formatter={formatter} />,
root
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
不使用dangerouslySetInnerHTML
主要问题是将字符串分解为链接/非链接字符串。这可以通过使用此答案中的代码来完成。我更新了代码以将字符串标记为匹配项,因此您可以相应地格式化它们。
const Linkify = ({ text, pattern, formatter }) => {
const arr = getSegments(pattern, text);
return arr.map(formatter);
};
const text = 'This is my phone number - 1234567890, and his is 34234123142';
const pattern = /\d+/g;
const formatter = ({ text, match }) => match ? <a href={`#${text}`}>{text}</a> : text;
ReactDOM.render(
<Linkify text={text} pattern={pattern} formatter={formatter} />,
root
);
function getSegments(rex, str) {
const segments = [];
let lastIndex = 0;
let match;
rex.lastIndex = 0; // In case there's a dangling previous search
while (match = rex.exec(str)) {
if (match.index > lastIndex) {
segments.push({ text: str.substring(lastIndex, match.index) });
}
segments.push({ text: match[0], match: true });
lastIndex = match.index + match[0].length;
}
if (lastIndex < str.length) {
segments.push({ text: str.substring(lastIndex) });
}
return segments;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
推荐阅读
- java - 错误:松弛通知失败。有关详细信息,请参阅 Jenkins 日志。最近更新后
- python - 我试图将我的 Tkinter 按钮绑定到键盘上的 Enter 键,但它不起作用
- php - 如何正确检查位 0 和无返回结果之间的差异
- c# - 远程主机使用 WCF 关闭了现有连接
- java - 界面工作簿、工作表和行与 Classess XSSFWorkbook、XSSFSheet 的混淆
- javascript - 迭代数组并在任何匹配和额外提供的属性值处收集特定数据
- c# - 当使用不存在的构建配置调用 dotnet build 时会发生什么?
- javascript - 为什么无法读取未定义的属性“0”
- ios - 在 swift/objective-c 中将 viewController 从项目导入库
- google-chrome - chrome 中的流事件:://tracing