Wrap all punctuation for CSS styling

I’m trying to write a plugin for a site in which the design has all punctuation styled a different colour to the rest of the text. Eg. Black letters and numbers, but all commas, full-stops, question marks, slashes etc. are, say, green.

Following the line of thought found here: Hanging punctuation, I’ve got this so far:

<?php

kirbytext::$post[] = function($kirbytext, $value) {

  $punctuation = array('/[:punct:]/');

  $values   = array_values($punctuation);
  $keys     = array_map(function($key) {
    return '<span class="accent-colour">' . $key . '</span>';
  }, array_keys($punctuation));

  return str_replace($keys, $values, $value);

};

Which doesn’t work. Wondering if I’m going down the right path?

I started out listing the punctuation individually, '.', ',', '?' etc (which also didn’t work) but thought a catch-all regex for punctuation would be better, except that I don’t know how that works in an array?

Using [[:punct:]] is not such a great idea, because then you would also replace HTML brackets, which would break your code, so better get all punctuation characters individually.

This line:

just gives you an array with the following element:

Array
(
    [0] => /[:punct:]/
)

What you need is a PHP function that finds all occurrences of your pattern and replaces them, see preg_replace_callback().

I’d still be very careful, because it’s easy to break stuff like this, if, for example, you replace a dot/question mark/colon in an href attribute etc. You would have to exclude all these possibilities. But where’s the point in highlighting punctuation marks, anyway. It doesn’t make your text more readable.