PHPでN番目にマッチした文字列だけ置換・変換する(正規表現も対応)

PHP

PHPでN番目にマッチした文字列だけ置換・変換する方法

この記事では「PHPでN番目にマッチした文字列だけ置換・変換する方法」について解説しています。
正規表現によるパターンマッチにも対応しています。

PHPにてpreg_replaceやstr_replaceなどで文字列を変換・置換する場合は多いと思います。

しかし、10個マッチするうちの3番目だけ変換したい!なんて場合もありますよね。
phpの標準の関数ではできませんので、今回サンプルを作ってみましたので紹介します。

正規表現と固定文字列パターンを指定する2パターン用意しましたが、どちらも使い方などはほぼ一緒です。

PHPでN番目にマッチした文字列だけ置換・変換するサンプルソース

<?php

/**
 * 文字列パターンにn番目にマッチした文字列だけ置換する
 *
 * ※こちらの方が正規表現版より高速に思えるが実際はほぼ変わらないことも多く、どちらも十分に高速なので特段気にする必要はない。
 * 参考) 30kのWebページにタグ変換を1万回やって約0.1秒
 *
 * @return string 置換された後の文字列
 * @param string 置換パターン(正規表現ではなく固定文字列)
 * @param string 置換する元の文字列
 * @param int 変換対象のN番目のマッチ(1番目~)
 */
function str_replace_nth($search, $replacement, $str, $nth) {

	if($nth < 1){
		return $str;
	}

	$offset = 0;
	$pos = strpos($str, $search, $offset);
	$match_count = 0;
	while($pos !== false){
		++$match_count;
		if($match_count == $nth){
			$str = substr_replace($str, $replacement, $pos, strlen($search));
			break;
		}
		//次の検索
		$offset = $pos + 1;
		$pos = strpos($str, $search, $offset);
	}
	return $str;

}

PHPでN番目にマッチした文字列だけ置換・変換するサンプルソース(正規表現版)

<?php


/**
 * 正規表現でn番目にマッチした文字列だけ置換する
 *
 * ※こちらの方が文字列パターン版よりも低速に思えるが実際はほぼ変わらないことも多く、どちらも十分に高速なので特段気にする必要はない。
 * 参考) 30kのWebページにタグ変換を1万回やって約0.1秒
 * 
 * @return string 置換された後の文字列
 * @param string 置換パターン(正規表現)
 * @param string 置換する元の文字列
 * @param int 変換対象のN番目のマッチ(1番目~)
 */
function preg_replace_nth($preg, $replacement, $str, $nth) {

	if($nth < 1){
		return $str;
	}

	$p = '/' . preg_quote($preg, '/') . '/';
	if (($result = preg_match_all($p, $str, $matches, PREG_OFFSET_CAPTURE)) >= $nth) {
		$str = substr_replace($str, $replacement, $matches[0][$nth-1][1], strlen($preg));
	}
	return $str;
}

コメント

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