[code]<?php
/**
Regex tree:

\A                    # Assert position at the beginning of the string
[\r\n]                # Match a single character present in the list below
                         # A carriage return character
                         # A line feed character
   *                     # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
(                     # Match the regular expression below and capture its match into backreference number 1
   [ \t]                 # Match a single character present in the list below
                            # The character " "
                            # A tab character
      +                     # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
[^\r\n]               # Match a single character NOT present in the list below
                         # A carriage return character
                         # A line feed character
   *+                    # Between zero and unlimited times, as many times as possible, without giving back (possessive)
[\r\n]                # Match a single character present in the list below
                         # A carriage return character
                         # A line feed character
   ++                    # Between one and unlimited times, as many times as possible, without giving back (possessive)
(?>                   # Atomic group.  Match the regex below, and do not try further permutations of it if the overall match fails.
   |                     # Match either the regular expression below (attempting the next alternative only if this one fails)
      \1                    # Match the same text as most recently matched by capturing group number 1
      [^\r\n]               # Match a single character NOT present in the list below
                               # A carriage return character
                               # A line feed character
         *+                    # Between zero and unlimited times, as many times as possible, without giving back (possessive)
      (?:                   # Match the regular expression below
                               # Match either the regular expression below (attempting the next alternative only if this one fails)
            [\r\n]                # Match a single character present in the list below
                                     # A carriage return character
                                     # A line feed character
               +                     # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
         |                     # Or match regular expression number 2 below (the entire group fails if this one fails to match)
            \z                    # Assert position at the very end of the string
      )
   |                     # Or match regular expression number 2 below (the entire group fails if this one fails to match)
      [\r\n]                # Match a single character present in the list below
                               # A carriage return character
                               # A line feed character
         +                     # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)+                    # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
\z                    # Assert position at the very end of the string

*/



/**
 * Unindent de gegeven string naar het begin van de regel indien mogelijk
 * 
 * Hierbij worden lege regels overgeslagen
 * 
 * N.b.: de langste substring wordt gebruikt, dus alle indenting moet exact
 * gelijk aan elkaar zijn, anders wordt wellicht niet alles gematcht
 * 
 * @param string $text
 * @return string
 */
function unindent($text) {
	// fix voor phphulp
	if (preg_match('{\A[\r\n]*([ \t]+)[^\r\n]*+[\r\n]++(?' . '>\1[^\r\n]*+(?:[\r\n]+|\z)|[\r\n]+)+\z}', rtrim($text), $match)) {
		$text = preg_replace('{^' . $match[1] . '}m', '', $text);
	}

	return $text;
}

/**
 * Indent een gegeven string naar een bepaalde diepte
 * 
 * @param string $text
 * @param numeric $indent hoe vaak moet $char vooraan iedere regel terugkomen
 * @param string $char welk karakter wordt gebruikt voor indenten
 * @return string
 */
function indent($text, $indent, $char = "\t") {
	return preg_replace('{^}m', str_repeat($char, $indent), $text);
}

/**
 * Deze functie is een combinatie van {@link unindent} en {@link indent}
 * 
 * @param string $text
 * @param numeric $indent hoe vaak moet $char vooraan iedere regel terugkomen
 * @param string $char welk karakter wordt gebruikt voor indenten
 * @return string
 */
function indentTo($text, $indent, $char = "\t") {
	return indent(unindent($text), $indent, $char);
}

//
// Voorbeeldje
//

$example = '
    Dit is een voorbeeld tekst!
  Zoals je ziet is deze regel origineel twee spaties geindent :-)

     En deze vijf!

   En deze maar drie. Kijken wat er gebeurt :-)
';

echo '<pre>', htmlspecialchars(
	unindent($example)
	. "\n\n" .
	indent($example, 1)
	. "\n\n" .
	indentTo($example, 1, '  ')
), '</pre>';
?>[/code]