2
votes

I am trying to create a simple php function to behave the same as the php trim() function, except that it preserves a single trailing line break if one exists. In addition, it needs to support preserving CRLF, CR and LF cases.

Consider the following use cases:

  1. myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \t ") === "The quick brown fox jumps over the lazy dog"
  2. myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\n\r\n \t \r\n ") === "The quick brown fox jumps over the lazy dog\r\n"
  3. myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\r \t \r ") === "The quick brown fox jumps over the lazy dog\r"
  4. myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \n\n \t \n ") === "The quick brown fox jumps over the lazy dog\n"

I have unsuccessfully tried a function such as:

public static function trimMessageBlock( $block )
{
    // Remove all leading whitespace (e.g. HT (9), LF (10), FF (12), CR (13), and space (32))
    $block = preg_replace("/^\s+/", "", $block);
    // Remove all trailing whitespace, but preserve a single trailing line break if one exists
    $block = preg_replace("/\s*(\R?)\s*$/", "$1", $block);

    return $block;
}

The above code seems to ignore the line break character entirely, and match only the simple case (\s*). The only other way I can see to do this is to use a "if" statement to test for a /\s*\R\s*$/ pattern first, then either use /\s*\R\s*$/ or /\s+$/, depending on if a newline is present of not. Any suggestions on a simpler, more elegant way to do this in regex?

BTW This is my first post to stackoverflow

2

2 Answers

0
votes

You could do it something like this. (see comments)

<?php

function myTrim($str) {
    //Look for a non whitespace character with whitespace following.
    //Capture the first (either 1 or 2) consecutive line ending characters
    if (preg_match("/[^\s]\s*?(\R)\s*$/", $str, $capture)) {
        // return the trimmed string, plus the line break
        return trim($str) . $capture[1];
    }
    //No line endings were found
    return trim($str);
}

var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \t ") === "The quick brown fox jumps over the lazy dog");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\n\r\n \t \r\n ") === "The quick brown fox jumps over the lazy dog\r\n");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\r \t \r ") === "The quick brown fox jumps over the lazy dog\r");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \n\n \t \n ") === "The quick brown fox jumps over the lazy dog\n");
//Added a couple more edge test cases
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \n\r\n \t \n ") === "The quick brown fox jumps over the lazy dog\n");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\n\n \t \n ") === "The quick brown fox jumps over the lazy dog\r\n");

//Outputs
//bool(true) bool(true) bool(true) bool(true) bool(true) bool(true)     
1
votes

Simplified...

function myTrim($str) {
    // if trailing line break exists, preserve it
    if ( preg_match("/\s*?(\R)\s*$/", $str, $capture) ) {
        // return the trimmed string, plus the line break
        return trim($str) . $capture[1];
    }

    // No line break was found, return the trimmed string
    return trim($str);
}

var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \t ") === "The quick brown fox jumps over the lazy dog");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\n\r\n \t \r\n ") === "The quick brown fox jumps over the lazy dog\r\n");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\r \t \r ") === "The quick brown fox jumps over the lazy dog\r");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \n\n \t \n ") === "The quick brown fox jumps over the lazy dog\n");
//Added a couple more edge test cases
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \n\r\n \t \n ") === "The quick brown fox jumps over the lazy dog\n");
var_dump(myTrim(" \t \r\n The quick brown fox jumps over the lazy dog \t \r\n\n \t \n ") === "The quick brown fox jumps over the lazy dog\r\n");