0

This is a Drupal 7/Views 3 question.

I am using a regex as a filter in a view to select Body fields with certain characteristics. However, when it comes to displaying the field, I don't want to display the entire body, just the match or matches.

For instance, for the following filter on the Body field for a match on regex:

<h[23456]>[^<]*[.!?:;,][^<]*</h[23456]>

I want to display a views Body match column which only displays any regex matches, not the entire Body field. So in this case I only want to display headings that have punctuation in them which are contained within the body.

This will not display to the public, so I'm not concerned with whether it's pretty, only whether it's readable. So it doesn't matter whether it displays HTML as HTML or as plain text.

However, the Rewrite Results field in the fields edit does not provide an option to match on regex for displaying the text.

How can I accomplish this?

1

You can create your own module that adds a field formatter for the text_with_summary field type. At the bare minimum you will need to implement the following hooks:

Here is an example that will do what you are asking for, but still requires a lot more work before you should use it in production. For example, it doesn't validate the pattern, and does not have an input field to enter the regex pattern in the Manage Display page for content types, even though it can be selected as a formatter.

/**
 * Implements hook_field_formatter_info().
 */
function my_module_field_formatter_info() {
  return array(
    'my_module_regex_formatter' => array(
      'label' => t('Regex matches'),
      'field types' => array('text', 'text_long', 'text_with_summary'),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function my_module_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $element = array();

  if ($display['type'] == 'my_module_regex_formatter') {
    $pattern = FALSE;
    if (isset($settings['my_module_regex_pattern'])) {
      $pattern = $settings['my_module_regex_pattern'];
    }
    if ($pattern) {
      foreach ($items as $delta => $item) {
        $matches = _my_module_get_regex_matches($pattern, $item['value']);
        $element[$delta] = array('#markup' => $matches);
      }
    }
  }

  return $element;
}

/**
 * Returns regex pattern matches.
 */
function _my_module_get_regex_matches($pattern, $subject) {
  $result = '';
  $regex_result = preg_match_all($pattern, $subject, $matches);
  if ($regex_result) {
    $result = '<ul>';
    foreach ($matches[0] as $match) {
      $result .= '<li>' . check_plain($match) . '</li>';
    }
    $result .= '</ul>';
  }
  return $result;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function my_module_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $default = '';
  if (isset($settings['my_module_regex_pattern'])) {
    $default = $settings['my_module_regex_pattern'];
  }
  $element = array();
  if ($display['type'] == 'my_module_regex_formatter') {
    $element['my_module_regex_pattern'] = array(
      '#type' => 'textfield',
      '#title' => t('Regex pattern'),
      '#default_value' => $default,
    );
  }

  return $element;
}

This will add Regex matches as an option in the Formatter select box within the Views configuration form for text fields, including the Body field. When you select the Regex matches formatter, a text input field will appear with the label Regex pattern. The pattern needs to include delimiters, and be properly escaped. The pattern in your question would look like this:

/\<h[23456]\>[^\<]*[\.!?:;,][^\<]*\<\/h[23456]\>/
  • The pattern is surrounded by a delimiter: /
  • All brackets are escaped: \<h, \>
  • The period is escaped: \.
  • The forward slash is escaped: \/h

preg_match_all() is used to perform a global regular expression match. The matches are outputted as an unordered list of escaped html (i.e. you will see the header tags in the output).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.