PHP Tips | 文字列処理:入力補助 - 改行数カウント

PHP PHP
スポンサーリンク

何をしたいユーティリティなのか

「改行数カウント」は、 ある文字列の中に「改行が何回含まれているか」を数えるためのユーティリティです。

問い合わせフォームの本文、コメント欄、メモ入力など、 ユーザーが自由に文章を書くところでは、改行がたくさん入ります。

改行の数を知っておくと、

  • 「何行まで」という制限をかけたい
  • ログに出すときに、行数が多すぎるものだけ特別扱いしたい
  • 画面表示のレイアウトを調整したい

といった場面で役に立ちます。

改行コードの種類をざっくり理解する

OS ごとに改行コードが違う

改行には、ざっくり 3 種類あります。

  • \n … LF(Linux・macOS など)
  • \r\n … CRLF(Windows)
  • \r … CR(古い Mac など、ほぼ見ないけど理屈上は存在)

Web フォームからの入力はほとんど \n ですが、 外部ファイルを読み込んだり、他システムと連携したりすると、 "\r\n" が混ざることもあります。

「改行数カウント」を作るときは、 この違いをどう扱うかを決めるのが大事なポイントです。

一番シンプルな版:LF(\n)だけ数える

フォーム入力だけを見るならこれで十分なことが多い

まずは、「\n の数だけ数える」シンプルな版からいきます。

/**
 * 文字列中の「LF 改行(\n)」の数を数える
 */
function count_newlines_lf(string $text): int
{
    // substr_count は「部分文字列が何回出てくるか」を数える関数
    return substr_count($text, "\n");
}
PHP

ここでの重要ポイントは、substr_count を使っていることです。 substr_count($haystack, $needle) は、「$haystack の中に $needle が何回出てくるか」を返してくれます。

フォーム入力(textarea)から来るテキストは、 ほとんどが \n 改行なので、これだけでも実務ではかなり役に立ちます。

例題で挙動を確認する

シンプルな複数行テキスト

$text = "1 行目\n2 行目\n3 行目";

echo count_newlines_lf($text); // 2
PHP

改行は 2 回なので、「改行数 2」が返ってきます。 「行数」としては 3 行ですね。

改行がない場合

$text = "これは 1 行だけのテキストです。";

echo count_newlines_lf($text); // 0
PHP

改行がないので、0 が返ってきます。

「行数」として扱いたい場合

改行数から行数を計算する

「改行数」だけでなく、「行数」を知りたいこともあります。 行数は「改行数+1」で計算できます(空文字は例外)。

/**
 * 文字列の「行数」を数える(LF 改行のみ対応)
 */
function count_lines_lf(string $text): int
{
    if ($text === '') {
        return 0;
    }

    return substr_count($text, "\n") + 1;
}
PHP

例:

$text = "1 行目\n2 行目\n3 行目";

echo count_lines_lf($text); // 3
PHP

「改行が 2 回 → 行数は 3 行」という関係が分かりやすくなります。

もう一歩:CRLF(\r\n)もきちんと扱う版

Windows 由来のテキストも考慮する

外部ファイルや他システムからのテキストには、 "\r\n"(CRLF)が含まれることがあります。

この場合、「\r\n を 1 回の改行として数える」ようにしたいですよね。

/**
 * 文字列中の「改行数」を数える(LF と CRLF に対応)
 */
function count_newlines(string $text): int
{
    // まず CRLF を LF にそろえる
    $normalized = str_replace("\r\n", "\n", $text);

    // (必要なら単独の \r も \n にそろえる)
    $normalized = str_replace("\r", "\n", $normalized);

    return substr_count($normalized, "\n");
}
PHP

ここでの重要ポイントは、「改行コードを一度そろえてから数えている」ことです。

  • \r\n\n
  • \r\n

に変換してしまえば、「改行は全部 \n」という前提で数えられます。

例題:CRLF が混ざる場合

$text = "1 行目\r\n2 行目\r\n3 行目";

echo count_newlines($text); // 2
PHP

CRLF を LF にそろえてから数えているので、 「改行数 2」として扱えます。

$text = "1 行目\r\n2 行目\n3 行目";

echo count_newlines($text); // 2
PHP

CRLF と LF が混ざっていても、 最終的には全部 LF になってから数えるので、 「改行数 2」として扱えます。

実務での使いどころ

入力制限:「改行は最大 N 回まで」にしたいとき

問い合わせフォームなどで、 「改行しすぎると読みづらいので、最大 10 行までにしたい」 といった制限をかけたいことがあります。

$body = $_POST['body'] ?? '';

$newlineCount = count_newlines($body);

if ($newlineCount > 9) { // 行数で言うと 10 行以上
    $error = '改行は 10 行までにしてください。';
}
PHP

改行数を見て制限をかけることで、 極端に長い・読みづらい入力を防げます。

ログに出すときに「行数が多いものだけ特別扱い」

ログにユーザー入力を出すとき、 行数が多すぎるものは「別ファイルに出す」「短縮する」などの扱いをしたいことがあります。

$body = $_POST['body'] ?? '';

if (count_newlines($body) > 20) {
    // 長文として別ログに出す
    error_log("long_body=\n" . $body);
} else {
    // 普通のログに出す
    error_log('body=' . $body);
}
PHP

改行数を基準に「長文かどうか」をざっくり判定できます。

もう一歩:行数と文字数を組み合わせた制限

「行数は N 行まで、1 行あたりの文字数は M 文字まで」

実務では、「行数」と「文字数」を組み合わせた制限をかけることもあります。

$body = $_POST['body'] ?? '';

$lines = explode("\n", str_replace("\r\n", "\n", $body));

if (count($lines) > 10) {
    $error = '行数は 10 行までにしてください。';
}

foreach ($lines as $i => $line) {
    if (mb_strlen($line, 'UTF-8') > 100) {
        $error = sprintf('%d 行目が 100 文字を超えています。', $i + 1);
        break;
    }
}
PHP

「改行数カウント」と「1 行ごとの文字数チェック」を組み合わせることで、 入力の“形”をかなり細かくコントロールできます。

まとめ:今日からの「改行数カウント」ユーティリティ

改行数カウントの本質は、「テキストの“行の多さ”を数値として扱えるようにする」ことです。

そのために、

  • substr_count($text, "\n") で LF の数を数える
  • CRLF や CR が混ざる場合は、先に str_replace で LF にそろえる
  • 必要なら「改行数+1」で行数として扱う

という処理を 1 本の関数に閉じ込めておきます。

もう一度、実務向けの基本形を載せておきます。

function count_newlines(string $text): int
{
    // 改行コードを LF にそろえる
    $normalized = str_replace("\r\n", "\n", $text);
    $normalized = str_replace("\r", "\n", $normalized);

    return substr_count($normalized, "\n");
}
PHP

もし、あなたのシステムで「長文入力が暴走している」「行数が多すぎてレイアウトが崩れる」と感じているなら、 その入力経路のどこかに、このユーティリティを一段かませてみてください。 テキストの“行の多さ”をちゃんと数えられるようになると、 入力のコントロールがぐっとやりやすくなります。

タイトルとURLをコピーしました