I have a sub that is supposed to play a music file.
I can locate MyDocuments easily.
I can even use Path.Combine to concatenate the rest of the string.
The full path should look something like this:
......Documents\JukeBox\MichaelJackson\01.wav
But I am getting double slashes not single ones
private static void playChoice(string band, int choice)
{
var myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string filename = "0" + choice;
string[] paths = { myDocs, "JukeBox", band, filename, ".wav" };
var fullPath = Path.Combine(#paths);
var player = new System.Media.SoundPlayer(fullPath);
player.Play();
}
A) How do I strip out the double slashes since my verbatim specifier does not work
B) The code looks awful - is there a better approach - or does anyone have a link to helpful literature
Verbatim string literals is a feature of string literals that affect how the literal is parsed.
You don't have any string literals; that is completely irrelevant.
#paths is a completely different feature that lets an identifier be named after a keyword (eg, int #int). It's also irrelevant.
You're probably seeing the value in the debugger, which displays the C# source to write the value, including escape sequences. Your string doesn't actually have double-slashes.
However, Path.Combine() combines folders (by adding slashes between them); it makes no sense to pass an extension there.
Related
I created a directory inside my WPF solution called Sounds and it holds sound files.(For example: mySound.wav).
Inside my code I use a List and there I have to add to those strings that relate to the sound files. In the beginning I used #"C:..." but I want it to be something like "UNIVERSAL" path. I tried using: "\Sounds\mySound.wav" but it generates an error.
The lines that I use there this directory are:
myList.Add("\Sounds\11000_0.2s.wav");//Error
using (WaveFileReader reader = new WaveFileReader(sourceFile))
where sourceFile is a string which express a path of the file.
Make sure that you check CopyToOutputDir in the properties of the soundfile, that will make sure the file is copied to the location you program runs from.
Also don't use single backslashes in the path since its an escape character.
Instead, do one of the following things:
Use a verbatim string:
#"Sounds\11000_0.2s.wav"
Escape the escape char:
"Sounds\\11000_0.2s.wav"
Use forward slashes:
"Sounds/11000_0.2s.wav"
For more information on string literals check msdn.
You either need to escape the / in the string or add the string literal indicator # at the beginning of the string.
Escape example:
var myFilePath = "c:\\Temp\\MyFile.txt";
String literal example:
var myFilePath = #"c:\Temp\MyFile.txt";
From path "//source/project/file.cs#232", I need to match file.cs
Match myMatch = Regex.Match(path, #"(\w+\.\w+)[^/]*$");
This would give file.cs in groups[1].
But for paths with dots in the file name, this doesn't work.
path "//source/project/file.initial.config.cs#232"
How could I modify this to work to give file.initial.config.cs?
Try this regex -- also into group 1, and assuming the extension can only be letters, numbers or the underscore:
.*/((?:.*?\.)+\w+)
This could be made more robust, if necessary, with knowledge of the allowable characters and suffixes for file naming, as well as details about the text in which (if) this file name is embedded. For example, if spaces were not allowed as part of the name
.*/((?:\S*?\.)+\w+)
or if ONLY letters, digits or the underscore are allowed:
.*/((?:\w*?\.)+\w+)
If we could be assured that there will be no dots or spaces after the last dot in the sequence, and spaces not allowed in the filename, it could be shortened further to:
.*/(\S*\.\w+)
to pick up everything between the last "/" and the last "." as well as any word characters after the last "."
etc
A number of non-'/' before '#':
/([^/]+)#
This should allow you to do what you want, or at least give you a better idea of how to achieve it:
/(\w+)(?:\..*)(\w{2,3})\#)
• example: http://regex101.com/r/wQ9jG2
Can you not simply modify your regex from (\w+\.\w+)[^/]*$ to (\w+(\.\w+)+)[^/]*$, to allow multiple occurrences of .words?
Why use regex, when you can do it in c# ?
I've created a function for you:
public static class FileNameHelper
{
public static string GetFileNameFromPath(string path, string extWithoutdot = "cs")
{
var startIndex = path.LastIndexOf('/') + 1;
var stringg = path.Substring(startIndex);
var remIndex = stringg.LastIndexOf("." + extWithoutdot) + extWithoutdot.Length+1;
return stringg.Remove(remIndex);
}
}
How to use ?
string filename=FileNameHelper.GetFileNameFromPath("//source/project/file.initial.config.cs#232","cs");
Remember to use the extension without .
See this has a lot of advantage over regex. They are:
Its not regex !
Its fast and efficient.
Its readable and pure c#
Note: Don't use regex in c# for trivial things. It's definitely a blow on the performance. First think of ways of achieving it in c#. Regex should be a last resort. Of course, if performance doesn't matter, use whatever !
By the way, mark it as answer if it helps. I know it'll help :)
If you're not averse to avoiding regular expressions, you could do this with just a small bit of string manipulation:
string mypath = "//source/project/file.initial.config.cs#232";
string filename = GetFileName(mypath);
static string GetFileName(string path)
{
var pathPieces = path.Split('/').Last().Split('#');
var filename = pathPieces.Take(pathPieces.Length - 1);
return String.Join("#", filename);
}
Easier, and works with any arbitrary filename (even those with spaces or # characters).
EDIT: Now works with filenames with # characters in them, although those are highly discouraged in Perforce.
(?<=/)[^/]+(?=#)
Using lookaround, it matches only the filename.
I need to trim a substring from a string, if that substring exists.
Specifically, if the string is "MainGUI.exe", then I need it to become "MainGUI", by trimming ".exe" from the string.
I tried this:
String line = "MainGUI.exe";
char[] exe = {'e', 'x', 'e', '.'};
line.TrimEnd(exe);
This gives me the correct answer for "MainGui.exe", but for something like "MainGUIe.exe" it doesn’t work, giving me "MainGUI" instead of "MainGUIe".
I am using C#. Thanks for the help!
Use the Path static class in System.IO namespace, it lets you strip extensions and directories from file names easily. You can also use it to get the extension, full path, etc. It's a very handy class and well worth looking into.
var filename = Path.GetFileNameWithoutExtension(line);
Gives you "MainGui", this is, of course, assuming you want to trim any file extension or you know your file is always going to be a .exe file, if you want to only trim extensions off of .exe files, however, and leave it on others. You can test first, either by using String.EndsWith() or by using the Path.GetExtension() method.
I would use Path.GetFileNameWithoutExtension instead of string manipulation to handle this.
string line = “MainGUI.exe”;
string fileWithoutExtension = Path.GetFileNameWithoutExtension(line);
If you only want to strip off the extension if it's .exe, you can check for that as well. The following will only strip off extensions of .exe, but leave all other extensions intact:
string ext = Path.GetExtension(line).ToLower();
string fileWithoutExtension = ext == ".exe"
? Path.GetFileNameWithoutExtension(line)
: line;
The Path class has a GetFileNameWithoutExtension.
If you are always trimming ".exe" you can trim the last 4 characters off regardless of the rest of the string.
line.Substring(0, line.Length - ".exe".Length);
string line = "MainGUI.exe";
if (line.EndsWith(".exe"))
line = line.Substring(0, line.Length - 4);
As no file extension has a dot (.) within it, you are safe to use this:
String line = "MainGUI.exe";
line = line.Substring(0, line.LastIndexOf('.'));
I have :
string Combine = Path.Combine("shree\\", "file1.txt");
string Combine1 = Path.Combine("shree", "file1.txt");
Both gives same result :
shree\file1.txt
What actually happen behind Path.Combine?Which is the best coding practice to do this.please clear my vision.Thanks.
If the first path (shree or shree\\) does not end with a valid separator character (e.g. DirectorySeparatorChar) it is appended to the path before concatenation.
So
string path1 = "shree";
string path2 = "file1.txt";
string combined = Path.Combine(path1, path2);
will result in "shree\file1.txt", while
string path1 = "shree\\";
already contains a valid separator character, so the Combine method will not add another one.
Here you typed two slashes in the string variable (path1). The first one just acts as an escape character for the second one. This is the same as using a verbatim string literal.
string path1 = #"shree\";
More information on the Combine method can be found on MSDN:
http://msdn.microsoft.com/en-us/library/fyy7a5kt.aspx
Use the second one. This way you don't care about what is the directory separator.
What actually happen behind Path.Combine?
It builds you a path... so it's doesn't matter what of those two you will use. but those \\ are redundant.
If you're interested with micro optimization, create a test which of the two is faster.
I have an application that requires me to "clean" "dirty" filenames.
I was wondering if anybody knew how to handle files that are named like:
1.0.1.21 -- Confidential...doc
or
Accounting.Files.doc
Basically there's no guarantee that the periods will be in the same place for every file name. I was hoping to recurse through a drive, search for periods in the filename itself (minus the extension), remove the period and then append the extension onto it.
Does anybody know either a better way to do this or how do perform what I'm hoping to do?
As a note, regEx is a REQUIREMENT for this project.
EDIT: Instead of seeing 1.0.1.21 -- Confidential...doc, I'd like to see: 10121 -- Confidential.doc
For the other filename, Instead of Accounting.Files.doc, i'd like to see AccountingFiles.doc
You could do it with a regular expression:
string s = "1.0.1.21 -- Confidential...doc";
s = Regex.Replace(s, #"\.(?=.*\.)", "");
Console.WriteLine(s);
Result:
10121 -- Confidential.doc
The regular expression can be broken down as follows:
\. match a literal dot
(?= start a lookahead
.* any characters
\. another dot
) close the lookahead
Or in plain English: remove every dot that has at least one dot after it.
It would be cleaner to use the built in methods for handling file names and extensions, so if you could somehow remove the requirement that it must be regular expressions I think it would make the solution even better.
Here is an alternate solution that doesn't use regular expressions -- perhaps it is more readable:
string s = "1.0.1.21 -- Confidential...doc";
int extensionPoint = s.LastIndexOf(".");
if (extensionPoint < 0) {
extensionPoint = s.Length;
}
string nameWithoutDots = s.Substring(0, extensionPoint).Replace(".", "");
string extension = s.Substring(extensionPoint);
Console.WriteLine(nameWithoutDots + extension);
I'd do this without regular expressions*. (Disclaimer: I'm not good with regular expressions, so that might be why.)
Consider this option.
string RemovePeriodsFromFilename(string fullPath)
{
string dir = Path.GetDirectoryName(fullPath);
string filename = Path.GetFileNameWithoutExtension(fullPath);
string sanitized = filename.Replace(".", string.Empty);
string ext = Path.GetExtension(fullPath);
return Path.Combine(dir, sanitized + ext);
}
* Whoops, looks like you said using regular expressions was a requirement. Never mind! (Though I have to ask: why?)