markdownから正規表現でdescriptionを生成

作成: 2020年11月06日

更新: 2021年03月29日

概要

markdownから生成したwebページのdescriptionをmarkdownの記号を除外して生成した.

方法

基本はmarkdownファイルの先頭から120文字を抽出して表示するがテーブルやコードブロックなどは除外してリンクや強調表示などは記号を除外して本文だけを表示するようにする.

正規表現を駆使して以下のようにした(Laravelのコードから一部抜粋).

$mdFilePath = public_path(("uploaded/" . $article->md_file));

$imgReg = '/!\[.*?\]\(.*?\)|!\[.*?\]\[.*?\]|\[.*?\]: .*?\"\".*?\"\"/';
$htmlReg = '/<(\".*?\"|\'.*?\'|[^\'\"])*?>/';
$headerReg = '/^#+? /m';
$brockquoteReg = '/^>.*$/m';
$horizontalReg = '/^(\* ){3,}$|^\*{3,}$|^(- ){3,}|^-{3,}$|^(_ ){3,}$|^_{3,}$/m';
$codeReg = '/^```.*?\r?\n(.*?\r?\n)*?```/m';
$tableReg = '/^( *\|[^\n]+\| *\r?\n)((?: *\|:?[-]+:?)+\| *)(\r?\n(?: *\|[^\n]+\| *\r?\n?)*)?$/m';
$emphasizeReg = '/\*(.*?)\*|_(.*?)_|\*\*(.*?)\*\*|__(.*?)__|~~(.*?)~~|`+?(.*?)`+?/';
$linkReg = '/\[(.*?)\]\((https?|ftp)(:\/\/[-_.!~*\\\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\)/';

$content = file_get_contents($mdFilePath);
$content = preg_replace($imgReg, '', $content);
$content = preg_replace($htmlReg, '', $content);
$content = preg_replace($headerReg, '', $content);
$content = preg_replace($brockquoteReg, '', $content);
$content = preg_replace($horizontalReg, '', $content);
$content = preg_replace($codeReg, '', $content);
$content = preg_replace($tableReg, '', $content);
$content = preg_replace($emphasizeReg, '$1$2$3$4$5$6', $content);
$content = preg_replace($linkReg, '$1', $content);
$content = preg_replace('/\r?\n/', '', $content);

$descriptionLength = 120;
if (mb_strlen($content) > $descriptionLength) {
    $description = mb_substr($content, 0, $descriptionLength) . '...';
    return view('blog.view', [
        'article' => $article,
        'relatedArticles' => $relatedArticles,
        'description' => $description
    ]);
} else {
    return view('blog.view', [
        'article' => $article,
        'relatedArticles' => $relatedArticles,
        'description' => $content
    ]);
}

注意点として

  • 各正規表現に一致するものが複数ある場合のために*や+使用時は?を使って貪欲マッチングをしないようにする.
  • mオプションを使って^や$を先頭,最後だけでなく行頭,行末もマッチするようにする
  • 改行を\nと\r\n両方に対応できるようにする

に気を付ける