EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

javaで文中のURLを個別にaタグ置換する

サービスの改善要望で、ユーザーが投稿する文中のURLを自動的にaタグに置換することになり、その実現方法について記載します。

文中のURLを一括でaタグに置換する

文中のURLを一括でaタグ置換する場合、正規表現で行うことができます。

private static final Pattern ptn =
        Pattern.compile
        ("(?<!href\\=\")(http://|https://){1}[\\w\\.\\-/:\\#\\?\\=\\&\\;\\%\\~\\+]+",
        Pattern.CASE_INSENSITIVE);


/**
 * 本文中のURLを一括でaタグに置換する
 * @return 置換後の本文
 * @param body 変換対象の本文
 */
public static String url2link(String body)
{
    Matcher matcher = ptn.matcher(body);
    return matcher.replaceAll("<a href=\"$0\">$0</a>");
}

個別に置換を行う

正規表現で一致したURLについて、例えば一部のドメインのみaタグに置換する等の対応が必要な場合、ドメイン毎にチェックを行う必要があります。
PHPでは標準でコールバック関数(preg_replace_callback)が用意されていますが、javaの場合は独自で実装行う必要があり、以下の様な形で実現できます。

/**
 * 本文中のURLで一致するドメインのみをaタグに置換する
 * @return 置換後の本文
 * @param body 変換対象の本文
 */
public static String url2link(String body)
{
    Matcher matcher = ptn.matcher(body);
    StringBuffer buffer = new StringBuffer();
    while (matcher.find()) {
        // マッチした部分を置換してbufferに結合
        matcher.appendReplacement(buffer, replaceUrl(matcher));
    }
    matcher.appendTail(buffer); // 末尾を結合
    return buffer.toString();
}

/** aタグ置換文字列作成 */
private static String replaceUrl(Matcher matcher) {
    if(matcher.group().toLowerCase().contains("ドメイン名")){
        //サブドメインも含めドメインが一致する場合aタグに変換
        return "<a href=\"" + matcher.group() + "\">" + matcher.group() + "</a>";

    }
    //ドメインが一致しない場合変換しないで返却
    return matcher.group();
}

上記ですが、URLの置換に限らず正規表現を変更すればいろんなパターンに応用できそうです。