将纯文本转换为JavaScript中的超链接

时间:2019-10-18 20:04:51

标签: javascript html reactjs

我有一个用例,需要识别字符串中的电话号码并将其转换为可点击的链接。当前无法使用外部库。

这是我到目前为止所做的:

字符串:“这是我的电话号码-1234567890” 我可以使用正则表达式模式将1234567890提取为电话号码。

我现在想将其替换为原始字符串,所以这就是我所做的:

 p { 
      font-family: Verdana; 
      font-size: 14px; 
      font-style: italic; 
      color: Green; 

 } 

 @media print { 
    p { 
        border-style: dashed;
    } 
 }

当我这样做时,我的输出是这样的,而不是将电话号码作为超链接获取:

const string = "This is my phone number - 1234567890"
const number = "1234567890"
const newString = '<a href="#">' + number + '</a>'
number = number.replace(number, newString);

如果我创建不带引号的newString,就像这样

This is my phone number - <a href="#">1234567890</a>

我的输出是这样的:

const newString = <a href="#">number</a>

如何使它成为可点击的链接?

4 个答案:

答案 0 :(得分:2)

您需要替换以用链接包装电话号码,然后使用dangerouslySetInnerHTML添加到React组件。

注意:之所以称为dangerouslySetInnerHTML,是因为您可以接受来自用户生成内容的XSS攻击。您应该先sanitise个字符串。

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的主要问题是将字符串分成链接/非链接字符串。可以使用此answer中的代码来完成。我已经更新了将字符串标记为匹配项的代码,因此您可以相应地设置其格式。

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>

答案 1 :(得分:1)

您并不是真的想为const newString设置一个'string',我将其更多地称为一个元素。您可以这样做:

const phoneEl = (
  <a href="#">
    {number}
  </a>
);

number是存储在名为number的变量中的电话号码。

那你要写:

<p>My phone number is - {phoneEl}</p>

我也建议

<href={`tel:${number}`}>

如果您希望人们能够单击链接并拨号。

答案 2 :(得分:-1)

在您的代码中,您没有操纵页面的DOM(html内容),因此结果不会显示在页面上。

以下是显示方法:

const number = "1234567890";
const myLink = `<a href="#">${number}</a>`;
document.querySelector('.myInfo').innerHTML = `This is my phone number - ${myLink}`;
<div class="myInfo">
  
</div>

答案 3 :(得分:-1)

const string = document.querySelector("body");
const text = string.innerText;

const textArr = text.split(" ").map(item => {
  if(item.match(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im)){
    item = `<a href="tel:${item}">${item}</a>`;
  }
  return item;
});

const newText = textArr.join(" ");

console.log({ newText })

string.innerHtml = newText;
<p class="body">
  This is my phone number - 555-555-5555
</p>