Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision 632627e1ead19fc7dc07effe441b2d543a675229)
+++ doc/user-guide/commands.xml	(revision f93fd2db1e8a4c2671ccae3cb9311ff47d4ba7e0)
@@ -1790,5 +1790,5 @@
 
 	<bitlbee-command name="blist">
-		<syntax>blist [all|online|offline|away]</syntax>
+		<syntax>blist [all|online|offline|away] [&lt;pattern&gt;]</syntax>
 		<short-description>List all the buddies in the current channel</short-description>
 
@@ -1796,4 +1796,8 @@
 			<para>
 				You can get a more readable buddy list using the <emphasis>blist</emphasis> command. If you want a complete list (including the offline users) you can use the <emphasis>all</emphasis> argument.
+			</para>
+
+			<para>
+				A perl-compatible regular expression can be supplied as <emphasis>pattern</emphasis> to filter the results (case-insensitive).
 			</para>
 		</description>
Index: root_commands.c
===================================================================
--- root_commands.c	(revision 632627e1ead19fc7dc07effe441b2d543a675229)
+++ root_commands.c	(revision f93fd2db1e8a4c2671ccae3cb9311ff47d4ba7e0)
@@ -1085,6 +1085,8 @@
 static void cmd_blist( irc_t *irc, char **cmd )
 {
-	int online = 0, away = 0, offline = 0;
+	int online = 0, away = 0, offline = 0, ismatch = 0;
 	GSList *l;
+	GRegex *regex = NULL;
+	GError *error = NULL;
 	char s[256];
 	char *format;
@@ -1102,4 +1104,13 @@
 		online = away = 1;
 	
+	if( cmd[2] )
+		regex = g_regex_new( cmd[2], G_REGEX_CASELESS, 0, &error );
+	
+	if( error )
+	{
+		irc_rootmsg( irc, error->message );
+		g_error_free( error );
+	}
+	
 	if( strchr( irc->umode, 'b' ) != NULL )
 		format = "%s\t%s\t%s";
@@ -1118,57 +1129,53 @@
 		bee_user_t *bu = iu->bu;
 		
-		if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
-		    ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) != BEE_USER_ONLINE )
+		if( !regex || g_regex_match( regex, iu->nick, 0, NULL ) )
+			ismatch = 1;
+		else
+			ismatch = 0;
+		
+		if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) )
 			continue;
 		
-		if( online == 1 )
-		{
-			char st[256] = "Online";
+		if( ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) == BEE_USER_ONLINE )
+		{
+			if( ismatch == 1 && online == 1 )
+			{
+				char st[256] = "Online";
+				
+				if( bu->status_msg )
+					g_snprintf( st, sizeof( st ) - 1, "Online (%s)", bu->status_msg );
+				
+				g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
+				irc_rootmsg( irc, format, iu->nick, s, st );
+			}
 			
-			if( bu->status_msg )
-				g_snprintf( st, sizeof( st ) - 1, "Online (%s)", bu->status_msg );
-			
-			g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
-			irc_rootmsg( irc, format, iu->nick, s, st );
-		}
-		
-		n_online ++;
-	}
-
-	for( l = irc->users; l; l = l->next )
-	{
-		irc_user_t *iu = l->data;
-		bee_user_t *bu = iu->bu;
-		
-		if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
-		    !( bu->flags & BEE_USER_ONLINE ) || !( bu->flags & BEE_USER_AWAY ) )
-			continue;
-		
-		if( away == 1 )
-		{
-			g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
-			irc_rootmsg( irc, format, iu->nick, s, irc_user_get_away( iu ) );
-		}
-		n_away ++;
-	}
-	
-	for( l = irc->users; l; l = l->next )
-	{
-		irc_user_t *iu = l->data;
-		bee_user_t *bu = iu->bu;
-		
-		if( !bu || ( irc->root->last_channel && !irc_channel_wants_user( irc->root->last_channel, iu ) ) ||
-		    bu->flags & BEE_USER_ONLINE )
-			continue;
-		
-		if( offline == 1 )
-		{
-			g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
-			irc_rootmsg( irc, format, iu->nick, s, "Offline" );
-		}
-		n_offline ++;
+			n_online ++;
+		}
+		
+		if( ( bu->flags & BEE_USER_ONLINE ) && ( bu->flags & BEE_USER_AWAY ) )
+		{
+			if( ismatch == 1 && away == 1 )
+			{
+				g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
+				irc_rootmsg( irc, format, iu->nick, s, irc_user_get_away( iu ) );
+			}
+			n_away ++;
+		}
+		
+		if( !(bu->flags & BEE_USER_ONLINE) )
+		{
+			if( ismatch == 1 && offline == 1 )
+			{
+				g_snprintf( s, sizeof( s ) - 1, "%s %s", bu->handle, bu->ic->acc->tag );
+				irc_rootmsg( irc, format, iu->nick, s, "Offline" );
+			}
+			n_offline ++;
+		}
 	}
 	
 	irc_rootmsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline );
+	
+	if( regex )
+		g_regex_unref( regex );
 }
 
