5

preg_replaceを使用して、複数のアンダースコアを1つのアンダースコアに置き換えるにはどうすればよいですか?

4

7 に答える 7

21

+演算子 (量指定子)は、最後の文字 (、文字クラス、キャプチャ グループ、または後方参照) の複数のインスタンスに一致します。

$string = preg_replace('/_+/', '_', $string);

これにより、 1 つ以上のアンダースコアが 1 つのアンダースコアに置き換えられます。


技術的には、質問のタイトルに対してより正しいのは、2つ以上を置き換えるだけです:

$string = preg_replace('/__+/', '_', $string);

または中かっこで量指定子を書きます:

$string = preg_replace('/_{2,}/', '_', $string);

そしておそらくそれからキャプチャして(戻る- )参照する:

$string = preg_replace('/(_)\1+/', '\1', $string);
于 2009-11-13T14:24:23.690 に答える
8
preg_replace('/[_]+/', '_', $your_string);
于 2009-11-13T14:24:17.113 に答える
7

単一のアンダースコアを置き換える必要がないため、実際には/__+/or/_{2,}/を使用するよりも優れています。/_+/これにより、preg バリアントの速度が向上します。

于 2009-11-13T17:29:20.743 に答える
7

テストを実行すると、次のことがわかりました。

while (strpos($str, '__') !== false) {
    $str = str_replace('__', '_', $str);
}

これより一貫して高速にするには:

$str = preg_replace('/[_]+/', '_', $str);

これでさまざまな長さのテスト文字列を生成しました:

$chars = array_merge(array_fill(0, 50, '_'), range('a', 'z'));
$str = '';
for ($i = 0; $i < $len; $i++) {  // $len varied from 10 to 1000000
    $str .= $chars[array_rand($chars)];
}
file_put_contents('test_str.txt', $str);

これらのスクリプトでテストされています (個別に実行されますが、 $lenの各値に対して同一の文字列に対して実行されます):

$str = file_get_contents('test_str.txt');
$start = microtime(true);
$str = preg_replace('/[_]+/', '_', $str);
echo microtime(true) - $start;

と:

$str = file_get_contents('test_str.txt');
$start = microtime(true);
while (strpos($str, '__') !== false) {
    $str = str_replace('__', '_', $str);
}
echo microtime(true) - $start;

短い文字列の場合、str_replace()メソッドはメソッドよりも 25% も高速preg_replace()でした。弦が長いほど差は小さくなりますが、str_replace()常に高速でした。

速度以外の理由で、ある方法を他の方法よりも好む人がいることは知っています。結果、テスト方法などに関するコメントを読んでいただければ幸いです.

于 2009-11-13T16:22:21.993 に答える
0

preg_replace()

+ 演算子が必要です

$text = "______";
$text = preg_replace('/[_]+/','_',$text);
于 2009-11-13T14:26:04.397 に答える