1

私の現在の問題は、単語とその略語でいっぱいのテーブルがあり、後でpreg_replace.

$search[] = '/\b'.$row['word'].'\b/i';  --WORDS TO ABBREVIATE
$abbrev[] = $row['abbrev'];             --LIST OF ABBREVIATIONS

//search and replace 
for($i = 0; $i<count($search); $i++)
{
     $title = = preg_replace($search[$i],$abbrev[$i], $title);
}

すべて正常に動作しているように見えますが、これが正しく変換されないという問題があります。

天国の地下室 --> 天国のS. 地下

S. は South の略です

記号/句読点の後の単語または文字が置き換えられないようにするにはどうすればよいですか? 私の正規表現の理解は限られているため、どんな助けでも大歓迎です。

4

3 に答える 3

1

代わりに、アサーションを使用して空白と開始 ( )をチェック\bできます。\s^

'/(?<=\s|^)' . $row['word'] . '\b/i'

現在、単語の前には、「単語以外の」文字ではなく、空白 (または文字列の先頭) を付ける必要があります。

別の注意として、ループは必要ありません。配列preg_replaceでも機能します。

$title = preg_replace($search, $abbrev, $title);

更新: アサーション構文に誤りがありました。動作するようになりました:実行例

テストコード:

$rows = [
  ['word' => 'S', 'abbrev' => 'South'],
  ['word' => 'W', 'abbrev' => 'West'],
  ['word' => 'N', 'abbrev' => 'North'],
  ['word' => 'E', 'abbrev' => 'East'],
];
foreach ($rows as $row) {
  $search[] = '/(?<=\s|^)' . preg_quote($row['word'], '/') . '\b/i';
  $abbrev[] = $row['abbrev'];
}

$title = "Heaven's Basement in W Virginia";
echo preg_replace($search, $abbrev, $title);

テスト結果:

Heaven's Basement in West Virginia

更新 2: (文字列の開始)の代わりに先読みアサーションと(文字列の終了) を使用して、単語の後に同じことを行うことができます。$^

'/(?<=\s|^)' . preg_quote($row['word'], '/') . '(?=\s|$)/i';
于 2013-02-18T15:30:36.193 に答える
0

のようなネガティブルックビハインドを利用できます'/(?<![\'])\b'.$row['word'].'\b/i'

于 2013-02-18T15:22:26.440 に答える
0

置換する各単語を複数回検索するよりも、入力をトークン化してコールバックで置換をチェックする方がよい場合があります。

function abbreviate($str, $abbr) {
    // Define a "word" as a utf-8 string beginning with a letter character
    // followed by as many letter characters or apostrophes as possible.
    // You will probably have to tweak this.
    $re = '/\w[\w\']*/u';
    $callback = function($matches) use ($abbr) {
        $replacement = $matches[0];
        $word = mb_strtolower($matches[0], 'utf-8');
        if (isset($abbr[$word])) {
            $replacement = $abbr[$word];
        }
        return $replacement;
    };
    return preg_replace_callback($re, $callback, $str);
}

echo abbreviate("Heaven's Basement\n", array('s'=>'S.'));
echo abbreviate("S College Rd\n", array('s' => 'South', 'rd'=> 'Road'));

プリント:

Heaven's Basement
South College Road
于 2013-02-18T15:22:51.500 に答える