Shortening Long File Paths

We're working on a little shell utility that displays paths in a menu. Some of these paths can get rather long, so I cooked up this little regular expression to shorten them. It's a replacement, so you call it like this:

static string PathShortener(string path)
{
    
const string pattern = @"^(w+:|)([^]+[^]+).*([^]+[^]+)$";
    
const string replacement = "$1$2...$3";
    
if (Regex.IsMatch(path, pattern))
    {
        
return Regex.Replace(path, pattern, replacement);
    }
    
else
    {
        
return path;
    }          
}

So, for these paths:

C:Documents and SettingsjatwoodMy DocumentsVisual Studio 2005SimpleEncryptionUnitTestsUnitTests.vb
wumpuspublicHilo DeliverablesHilo FinalIntroductionCodeIntroApp_Themescellphonephoto-small.jpg

The result is:

C:Documents and Settingsjatwood...UnitTestsUnitTests.vb
wumpuspublic...cellphonephoto-small.jpg

The general strategy is to keep the first two folders at the beginning, replace the middle with an ellipsis, and leave the final folder and filename on the end.

After spending an hour dinking around with this and testing it on a bunch of paths, a colleague pointed me to the Windows API call PathCompactPathEx, which (almost) does the same thing. Doh!

[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPathEx([Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);

static string PathShortener(string path, int length)
{
    
StringBuilder sb = new StringBuilder();
    
PathCompactPathEx(sb, path, length, 0);
    
return sb.ToString();
}

As you can see from the API definition for PathCompactPathEx, this works a little differently. It lets you set an absolute length for the path, and displays as many characters as it can with a "best fit" placement of the ellipsis. Here's the output for our two paths:

C:Documents and Settingsjatwood...UnitTests.vb
wumpuspublicHilo Deliverab...photo-small.jpg

So, which to choose? CompactPathEx guarantees that the paths will always be exactly (x) characters while displaying as much as it can, but it may not be able to split cleanly. My regex always splits cleanly, but makes no guarantees on length.

And obviously, if you're not running Windows, or if you don't care for p/invoke, the API call is clearly out.

Related posts

Testing With "The Force"

Markdown was one of the humane markup languages that we evaluated and adopted for Stack Overflow. I've been pretty happy with it, overall. So much so that I wanted to implement a tiny, lightweight subset of Markdown for comments as well. I settled on these three commonly used

By Jeff Atwood ·
Comments

Regular Expressions: Now You Have Two Problems

I love regular expressions. No, I'm not sure you understand: I really love regular expressions. You may find it a little odd that a hack who grew up using a language with the ain't keyword would fall so head over heels in love with something as

By Jeff Atwood ·
Comments

We Don't Use Software That Costs Money Here

Whenever the regular expression topic comes up, I unashamedly recommend the best tool on the market for parsing and building regular expressions -- RegexBuddy. But there's one tiny problem. RegexBuddy costs money. I've always encountered vague resistance when recommending commercial tools that I considered best of

By Jeff Atwood ·
Comments

Regex use vs. Regex abuse

I’m a huge fan of regular expressions; they’re the Swiss army knife of web-era development tools. I’m always finding new places to use them in my code. Although other developers I work with may be uncomfortable with regular expressions at first, I eventually convert them to the

By Jeff Atwood ·
Comments

Recent Posts

Stay Gold, America

Stay Gold, America

We are at an unprecedented point in American history, and I'm concerned we may lose sight of the American Dream.

By Jeff Atwood ·
Comments
The Great Filter Comes For Us All

The Great Filter Comes For Us All

With a 13 billion year head start on evolution, why haven’t any other forms of life in the universe contacted us by now? (Arrival is a fantastic movie. Watch it, but don’t stop there – read the Story of Your Life novella it was based on for so much

By Jeff Atwood ·
Comments
I Fight For The Users

I Fight For The Users

If you haven’t been able to keep up with my blistering pace of one blog post per year, I don’t blame you. There’s a lot going on right now. It’s a busy time. But let’s pause and take a moment to celebrate that Elon Musk

By Jeff Atwood ·
Comments
The 2030 Self-Driving Car Bet

The 2030 Self-Driving Car Bet

It’s my honor to announce that John Carmack and I have initiated a friendly bet of $10,000* to the 501(c)(3) charity of the winner’s choice: By January 1st, 2030, completely autonomous self-driving cars meeting SAE J3016 level 5 will be commercially available for passenger use

By Jeff Atwood ·
Comments