匹配字符串中的单词并在找到匹配项时替换整个单词

时间:2015-11-05 09:57:53

标签: php regex drupal

我正忙着学习Drupal / PHP并且有一个问题我希望有人可以提供帮助。我已经读过这篇文章的其他和类似的帖子,但是尝试解决方案还没有成功,因此提出了一个新问题。

我正在尝试调整现有的Drupal模块(wordfilter for D7,dev release),它将替换任何亵渎的实例。举个例子,如果给定的字符串包含要替换的字符串'word',那么我需要匹配整个单词,而不仅仅是有问题的字符,所以

措辞措辞措辞。字!'

需要成为

'<deleted> <deleted> got <deleted>. <deleted>!' 

而不是

'<deleted>ing <deleted>er got <deleted>ed. <deleted>!'. 

到目前为止我的代码有几个问题。首先,它只取代完全匹配,而不是整个单词。其次,我有分隔符和转义字符的问题。我已经标记了认为问题所在的问题**问题1和**问题2.如果我错了,请告诉我。

问题2抛出的错误是

Warning: preg_replace(): Unknown modifier '$'

我认为这与某些未正确转义的字符有关。我试着用escapers包装$ pattern变量,所以它读取

$text = preg_replace('/' . $pattern . '/', "\${1}" . $replacement . "\${2}", $text);

但没有运气。然后正则表达式没有匹配任何东西。问题可能出在正则表达式本身,但我很确定它是正确的。我正在使用的模式是

$pattern = '^(.*?(\B'word'\B)[^$]*)$';

但'word'被包含在preq_quote调用中。

所以你去吧。你们所有人都可能会被撕成碎片。我相信你们都能闻到血液:-)如果我需要重写整个功能,那就这样吧。如果这是一个快速解决方案,那就更好了。如果我错过了任何内容,或者您​​想要更多信息,请告诉我,我会编辑问题以包含它。任何帮助都会非常感激,就像我说的那样,我把这种方法作为一种学习练习,所以所有(建设性的)批评都受到欢迎。

/**
 * hook_filter process operation callback.
 */
function wordfilter_filter_process($text) {
  //dpm($text);
  $text = ' ' . $text . ' ';
  $list = _wordfilter_list();


  $utf8 = variable_get('wordfilter_use_utf8_flag', FALSE);
  $case_sensitive = variable_get('wordfilter_process_case_sensitive', FALSE);
  $default_replacement = variable_get('wordfilter_default_replacement', '[filtered word]');

  //dpm($list);

  foreach ($list as $word) {
    // Prevent mysterious empty value from blowing away the node title.
    if (!empty($word->words)) {
      $replacement = ($word->replacement) ? $word->replacement : $default_replacement;

      if ($replacement == '<none>') {
        $replacement = '';
      }

      if ($word->standalone) {
        $pattern = '/(\W)' . preg_quote($word->words, '/') . '(\W)/';
      }
      else { //**issue 1
        //$pattern = '/' . preg_quote($word->words, '/') . '/';
        $pattern = '^(.*?(\B' . preg_quote($word->words, '/') . '\B)[^$]*)$';
      }

      if (!$case_sensitive) {
        $pattern .= 'i';
      }

      if ($utf8) {
        $pattern .= 'u';
      }

      $split_text = preg_split('/(<[^>]*>)/i', drupal_substr($text, 1, -1), -1, PREG_SPLIT_DELIM_CAPTURE);
      $split_text = array_values(array_filter($split_text));

      if (count($split_text) > 1) {
        $new_string = '';
        foreach ($split_text as $part) {
          if (!preg_match('/^</', $part)) {
            //dpm($part);
            $new_string .= preg_replace($pattern, "\${1}" . $replacement . "\${2}", $part);
            //$new_string .= preg_replace($pattern, $replacement, $part);
          }

          else {
            $new_string .= $part;
          }
        }
      }

      else { //**issue 2
        $text = preg_replace($pattern, "\${1}" . $replacement . "\${2}", $text);
        //$text = preg_replace($pattern, $replacement, $text);
      }
    }
  }
  $text = drupal_substr($text, 1, -1);

  return $text;
}

1 个答案:

答案 0 :(得分:1)

\bword\w*

你可以简单地使用它。参见演示。

https://regex101.com/r/lR1eC9/7