Home > Net >  Remove specific characters except last
Remove specific characters except last

Time:02-23

I have a text string and I want to replace the dots with underscores except for the last character found in the string.

Example:

input = "video.coffee.example.mp4"
result = "video_coffe_example.mp4"

I have a code but this replaces everything including the last character

first option failed

static string replaceForUnderScore(string file)
{
     return file = file.Replace(".", "_");
}

I implemented a second option that works for me but I find that it is very extensive and not very optimized

static string replaceForUnderScore(string file)
{
     string result = "";

     var splits = file.Split(".");
     var extension = splits.LastOrDefault();

     splits = splits.Take(splits.Count() - 1).ToArray();

     foreach (var strItem in splits)
     {
         result = result   "_"   strItem;
     }

     result = result.Substring(1, result.Length-1);
     string finalResult = result   "." extension;

     return finalResult;
 }

Is there a better way to do it?

CodePudding user response:

Since you work with files, I suggest using Path class: all we want is to change file name only while keeping extension intact:

static string replaceForUnderScore(string file) =>
  Path.GetFileNameWithoutExtension(file).Replace('.', '_')   Path.GetExtension(file);

CodePudding user response:

Off the top of my head but this might work.

return $"{file.Replace(".mp4","").Replace(".","_")}.mp4";

CodePudding user response:

Regex will help you to do this.

Add the namespace using System.Text.RegularExpressions;

And use this code:

var regex = new Regex(Regex.Escape("."));
var newText = regex.Replace("video.coffee.example.mp4", "_", 2);

Here we specified the maximum number of times to replace the .

The output would be the following:

video_coffee_example.mp4

CodePudding user response:

The simplest (and probably fastest) way is just to iterate over the string:

static string replaceForUnderScore(string file)
{
  StringBuilder sb      = new StringBuilder( file.Length ) ;
  int           lastDot = -1 ;

  for ( int i = 0 ; i < file.Length ;   i )
  {
    char c = file[i] ;

    // if we found a '.', replace it with '_' and save its position
    if ( c == '.' )
    {
      c       = '_' ;
      lastDot = i   ;
    }


    sb.Append( c ) ;

  }

  // if we changed any '.' to '_', convert the last such replacement back to '.'
  if ( lastDot >= 0 )
  {
    sb.Replace ( '.' , '_' , lastDot, 1 );
  }

  return sb.ToString();
}

Another approach would be to use System.IO.Path. It's certainly the most succinct:

static string replaceForUnderScore( string file )
{
  string ext  = Path.GetExtension( file ) ;
  string name = Path
                .GetFileNameWithoutExtension( file )
                .Replace( '.' , '_' )
                ;

  return Path.ChangeExtension( name , ext ) ;
}

CodePudding user response:

You can replace all the dots with an underscore except for the last dot by asserting that there is still a dot present to the right when matching one.

string result = Regex.Replace(input, @"\.(?=[^.]*\.)", "_");

The result will be

video_coffee_example.mp4
  • Related