Соответствующие слова в строке и заменить все слово, если найдено совпадение

1

Я занят поиском Drupal/PHP и имею проблему, на которую я надеюсь, кто-то может помочь. Я читал другие и подобные сообщения этому, но опробовать решения не получилось, поэтому задал новый вопрос.

Я пытаюсь адаптировать существующий модуль Drupal (wordfilter для D7, dev release), который заменит любой экземпляр ненормативной лексики альтернативой. Так, например, если заданная строка содержит заменяемую строку "слово", мне нужно сопоставить все слово, а не только оскорбительные символы, поэтому

"формулировка нарушителя была сформулирована. слово!'

должен стать

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

и не

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

Код, который у меня есть, имеет пару проблем. Во-первых, он заменяет точное совпадение, а не целое слово. Во-вторых, у меня проблема с разделителями и escape-символами. Я отметил, что, по-моему, проблемы с ** проблемой 1 и ** проблемой 2. Если я ошибаюсь, сообщите мне.

Ошибка, вызванная выпуском 2,

Warning: preg_replace(): Unknown modifier '$'

который, как мне кажется, связан с тем, что некоторые персонажи не сбежались правильно. Я попытался обернуть переменную $ pattern с помощью escapers, чтобы он читал

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

но не повезло. Регулярное выражение тогда ничего не соответствовало. Проблема может быть в самом регулярном выражении, но я уверен, что это правильно. Я использую шаблон

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

но "слово" завершается вызовом 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;
}
Теги:
drupal

1 ответ

1
\bword\w*

Вы можете просто использовать это. Смотрите демоверсию.

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

  • 0
    Я думаю, что ваш шаблон регулярных выражений является определенным улучшением по сравнению с тем, что я имел, так что спасибо вам за это. Тем не менее, ошибка все еще возникает из-за неизвестного модификатора в позиции ** выпуск 2 в последнем операторе 'else'.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню