Formatting fractions found in a given string to html fraction I'm working on a site running woocommerce and wp where the user will add/has added a dimension attribute. 

The dimension string will take the following format originally:

Ht: 30 1⁄2" W: 22 1⁄2" D: 18"

and should return the string with html to format the fraction e.g:

Ht: 30 &lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;2&lt;/sub&gt;" W: 22 &lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;2&lt;/sub&gt;" D: 18"

will the following to consider:


The amount of fractions in the string will be unknown (0 - X)
The string can be any valid fraction
The user may/may not add a space in between the fraction and the quotation e.g Ht: 30 1/2 " W...


Here's my solution:

add_filter( 'woocommerce_attribute', __NAMESPACE__ . '\\format_dimension_attr', 10, 2 );


/**
 * Format fractions in the Dimension attr string to include proper html
 *
 * e.g The 1/2 in 'Height: 5 1/2"' should be
 *
 * &lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;2&lt;/sub&gt;
 */
function format_dimension_attr( $value, $att ) {

    if ( 'Dimensions' === $att['name'] ) {
        // Use the raw value instead of $value (which includes html)
        $raw = $att-&gt;get_options()[0];

        if ( strpos( $raw, '/' ) !== false ) {

            $raw = explode( ' ', $raw );

            // Check for accidental space before quotation and remove it
            // e.g 'height: 5 1/2 "' will produce [5, 1/2, "]
            $raw = array_filter( $raw, function( $val ) {
                return '"' !== $val;
            } );

            // Run through the array
            $raw = array_map( function( $val ) {

                // Format the current item if it contains a slash
                if ( strpos( $val, '/' ) !== false ) {
                    // Remove any " before splitting
                    $val = explode( '/', trim( $val, '"' ) );
                    $val = '&lt;sup&gt;' . $val[0] . '&lt;/sup&gt;&amp;frasl;&lt;sub&gt;' . $val[1] . '&lt;/sub&gt;"';
                }

                return $val;

            }, $raw );

            // Replace the p tag we removed by using the raw value
            $value = wpautop( join( ' ', $raw ) );
        }
    }

    return $value;
}
Well, regex is often a bad idea, but it's one of the case I find it way better than the alternative :

$raw='30 1/2 et 22 3 / 4';
echo preg_replace('/([0-9]+)\s*\/\s*([0-9]+)/', '&lt;sup&gt;$1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;$2&lt;/sub&gt;',$raw);


Just test it and see for yourself.