この記事ではコメントなどのテキスト内の任意の文字列をリンクに変換する方法をサンプルコード付きでご紹介します。
テキスト内の任意の文字列とは具体的に
- URL
- ハッシュタグ(#hogehoge)
- メンション(@hogehoge)
です。
これらの文字列をテキストリンクすることによってクリックしたユーザーに任意の挙動をさせることができます。
また、ユーザビリティが向上します。
後述するサンプルコードは以下のように動作します。
テキストボックス内でURLなどを含めたテキストを入力するとテキストボックスの下にリンクにして表示しています。
目次
サンプルコード
以下のコードはテキスト内のハッシュタグやURLなどをテキストリンクにするサンプルコードです。
/**
* テキスト内のハッシュタグやURLをリンクにする
* @param comment
* @returns
*/
export const textToLink = (comment: string) => {
// 正規表現でURLを抽出
const regexp_url = /(https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-]+)/g;
let linkedComment = comment.replace(regexp_url, '<a href="$1">$1</a>');
// 正規表現で#を抽出
const regexp_hash = /#+([a-zA-Z0-9亜-熙ぁ-んァ-ヶー-龥朗-鶴.\-_]+)/g;
linkedComment = linkedComment.replace(
regexp_hash,
'<a href="/search?q=$1&type=hash">#$1</a>'
);
// 正規表現で@を抽出
const regexp_at = /@+([a-zA-Z0-9亜-熙ぁ-んァ-ヶー-龥朗-鶴.\-_]+)/g;
linkedComment = linkedComment.replace(
regexp_at,
'<a href="/search?q=$1&type=at">@$1</a>'
);
return linkedComment;
};
import React, { useState } from "react";
import { textToLink } from "./utility";
import TextField from "@mui/material/TextField";
export default function App() {
const [comment, setComment] = useState<string>("");
return (
<>
<TextField
label="コメント"
value={comment}
rows={5}
fullWidth
multiline
onChange={(e) => setComment(e.target.value)}
/>
<br />
<br />
↓ハッシュタグやURLなどをリンクに変換
<div
dangerouslySetInnerHTML={{
__html: textToLink(comment)
}}
style={{
whiteSpace: "pre-wrap",
lineHeight: "176%",
fontSize: ".9rem"
}}
/>
</>
);
}
任意の文字列をリンクに変換するときのポイント
サンプルコードでポイントとなる部分は以下のとおりです。
- 正規表現でURLを抽出
- 正規表現でハッシュタグやメンションを抽出
- テキストリンクに置き換える
以下でそれぞれについて説明します。
正規表現でURLを抽出
URLを正規表現で表すと以下のようになります。
こちらは 検索したらすぐに見つけることができます。
// URLの正規表現
const regexp_url = /(https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-]+)/g;
正規表現でハッシュタグやメンションを抽出
ハッシュタグとメンションはを正規表現で表すと以下のようになります。
ハッシュタグは#、メンションは@hiro9nob
- 小文字の英字
- 大文字の英字
- 数字
- 漢字
- ひらがな
- カタカナ
- 記号(.-_)
の組み合わせをテキストリンクにします。
// ハッシュタグの正規表現
const regexp_hash = /#+([a-zA-Z0-9亜-熙ぁ-んァ-ヶー-龥朗-鶴.\-_]+)/g;
// メンションの正規表現
const regexp_at = /@+([a-zA-Z0-9亜-熙ぁ-んァ-ヶー-龥朗-鶴.\-_]+)/g;
テキストリンクに置き換える
正規表現で抽出したい文字列をしていたらreplaceで抽出テキストをテキストリンクに置き換えます。
// 正規表現でURLを抽出
const regexp_url = /(https?:\/\/[\w/:%#\$&\?\(\)~\.=\+\-]+)/g;
let linkedComment = comment.replace(regexp_url, '<a href="$1">$1</a>');
テキストリンクに置き換えるときに$1と記述していますが、このスクリプトはキャプチャリンググループです。
$1には正規表現で一致した文字列が入ります。
replaceのキャプチャリンググループがよくわからない場合は「文字列内の単語の交換」を参考にしてください。
Reactの参考書をまとめておきます。
コメント