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. 是 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

您可以使用负面的lookbehind like '/(?<![\'])\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 回答