Armelの答えは機能しますが、最適に機能していません。はい、必要な出力にはワード境界と大文字と小文字を区別しないマッチングが必要ですが、次のようになります。
- ワード境界は、括弧で囲まれても何も得られません。
preg_match()
ブラックリスト配列の各要素に対して反復呼び出しを実行することは効率的ではありません。そうすることで、正規表現エンジンに、文字列全体に対する個々のキーワードチェックのウェーブの後にウェーブを実行するように要求します。
文字列をトラバースする各ステップですべてのキーワードを1回チェックする単一の正規表現パターンを作成することをお勧めします。|
単一パターンを動的に生成するには、要素のブラックリスト配列を正規表現の「OR」コマンドを表す(パイプ)で内破するだけです。パイプで区切られたすべてのキーワードをキャプチャしないグループ((?:...)
)でラップすることにより、wordboundaries(\b
)はブラックリスト配列内のすべてのキーワードの目的を果たします。
コード:(デモ)
$string = "Each person wants peaches for themselves forever";
$blacklist = array("for", "each");
// if you might have non-letter characters that have special meaning to the regex engine
//$blacklist = array_map(function($v){return preg_quote($v, '/');}, $blacklist);
//print_r($blacklist);
echo "Without wordboundaries:\n";
var_export(preg_replace('/' . implode('|', $blacklist) . '/i', '', $string));
echo "\n\n---\n";
echo "With wordboundaries:\n";
var_export(preg_replace('/\b(?:' . implode('|', $blacklist) . ')\b/i', '', $string));
echo "\n\n---\n";
echo "With wordboundaries and consecutive space mop up:\n";
var_export(trim(preg_replace(array('/\b(?:' . implode('|', $blacklist) . ')\b/i', '/ \K +/'), '', $string)));
出力:
Without wordboundaries:
' person wants pes themselves ever'
---
With wordboundaries:
' person wants peaches themselves forever'
---
With wordboundaries and consecutive space mop up:
'person wants peaches themselves forever'
ps/ \K +/
は、供給される2番目のパターンです。preg_replace()
これは、入力文字列が2回目に読み取られ、2つ以上の連続するスペースを検索することを意味します。 \K
「ここからフルストリングマッチを再開する」という意味です。事実上、以前に一致したスペースを解放します。次に、続く1つ以上のスペースが一致し、空の文字列に置き換えられます。