Fix auto_link() for the Nth time

 - anchor() is for local links and breaks ones that don't have a protocol prefix
 - Allow :// links (no actual protocol specified)
 - Further simplified the URL regular expression
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index a6536cf..d0fab3f 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -384,22 +384,23 @@
 	function auto_link($str, $type = 'both', $popup = FALSE)
 	{
 		// Find and replace any URLs.
-		if ($type !== 'email' && preg_match_all('#\b(([\w-]+://?|www\.)[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#', $str, $matches, PREG_OFFSET_CAPTURE))
+		if ($type !== 'email' && preg_match_all('#(\w*://|www\.)[^\s()<>;]+\w#i', $str, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER))
 		{
 			// Set our target HTML if using popup links.
-			$target = ($popup) ? 'target="_blank"' : '';
+			$target = ($popup) ? ' target="_blank"' : '';
 
 			// We process the links in reverse order (last -> first) so that
 			// the returned string offsets from preg_match_all() are not
 			// moved as we add more HTML.
-			foreach (array_reverse($matches[0]) as $match)
+			foreach (array_reverse($matches) as $match)
 			{
-				// $match is an array generated by the PREG_OFFSET_CAPTURE flag.
-				// $match[0] is the matched string, $match[1] is the string offset.
-
-				$anchor = anchor($match[0], '', $target);
-
-				$str = substr_replace($str, $anchor, $match[1], strlen($match[0]));
+				// $match[0] is the matched string/link
+				// $match[1] is either a protocol prefix or 'www.'
+				//
+				// With PREG_OFFSET_CAPTURE, both of the above is an array,
+				// where the actual value is held in [0] and its offset at the [1] index.
+				$a = '<a href="'.(strpos($match[1][0], '/') ? '' : 'http://').$match[0][0].'"'.$target.'>'.$match[0][0].'</a>';
+				$str = substr_replace($str, $a, $match[0][1], strlen($match[0][0]));
 			}
 		}