C# file upload: no groups from reg ex? - c#

this code was working fine till this morning, can anyone spot my mistake? probably really silly but it has me stumped!
i use a form to submit a file (field name 'fileUpEx'), and then i wrote a class to upload it (like i said, it's been working for ages)....
(if i write 'filepath' to the page it is 'Test copy.pdf')
My class returns 'no groups'!!!
Very odd, can anyone please help?
string filepath = fileUpEx.PostedFile.FileName;
string pat = #"\\(?:.+)\\(.+)\.(.+)";
Regex r = new Regex(pat);
Match m = r.Match(filepath);
if (m.Groups[0].Captures.Count != 0)
{
//blaa blaa blaa
}
else
{
return "no Groups";
}
Thanks in advance,
Vauneen

Your regular expression requires that the file path contains a backslash which it doesn't. You could perhaps make that part optional, for example:
#"(?:\\.+\\)?(.+)\.(.+)"
Alternatively you could use the methods available in System.IO.Path:
string extension = Path.GetExtension(filePath);
string filename = Path.GetFilenameWithoutExtension(filePath);

Related

get the name of a file without empty spaces

I´m working in a MVC project and receive a file(HttpPostedFileBase property) in my controller via modelbinding and what I want is to delete all the empty spaces in the name of the file I just received, for that purpose I use this
var nombre_archivo = DateTime.Now.ToString("yyyyMMddHHmm.") +"_"+ (info.file.FileName.ToString()).Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
but the var "nombre_archivo" is always: 201801240942.System.String[] and what I want is 201801240942.nameOfFile, could you please tell me where is the error?
Your are splitting on an array of dots.
Use replace instead :
var nombre_archivo = string.Format("{0}_{1}",
DateTime.Now.ToString("yyyyMMddHHmm."),
info.file.FileName.replace(" ", "")
);
Moreover, we recommend to use string.Format instead of + concatenation. It's faster and clearer
var name = $"{DateTime.Now.ToString("yyyyMMddHHmm.")}_{info.file.FileName.Replace(" ", "")}";
You can use String.Replace to replace a space with an empty string. The method has other issues though. It doesn't check whether FileName is valid which means someone could make a POST request with a hand-coded path like ../../ or E:\somepath\myinnocentprogram.exe to write a file to the server's disk. Or worse, ../index.htm.
Replacing spaces doesn't make much sense. It's the dots and slashes that can result
If you check Uploading a File (Or Files) With ASP.NET MVC you'll see that the author uses Path.GetFileName() to retrieve only the file's name before saving it in the proper folder. Your code should look like this::
[HttpPost]
public ActionResult Index(HttpPostedFileBase file) {
if (file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName)
.Replace(" ","");
var finalName=String.Format("{0:yyyyMMddHHmm}._{1}",DateTime.Now,fileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), finalName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
This ensures that only the filename part of the file is used, and that the file is saved in the appropriate folder, even if someone posted an invalid path
This is how you should be able to fix your problem
string nombre_archivo = string.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddHHmm."), info.file.FileName.Where(c => !Char.IsWhiteSpace(c))
EDIT :
You should use string.Replace instead of using Linq query.
There is a format problem I did not expect.
So, the right answer is given below, but basically, it would look like :
string nombre_archivo = string.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddHHmm."), info.file.FileName.Replace(" ", ""));

c# Regex for file extension embedded in a string

I need to extract file extension that is embedded in a connection string. I was wondering if it's possible to achieve it using Regex? or any solution would be of great help. The connection string looks something similar to this:
"Provider=MSDASQL.1;Persist Security Info=False;Extended
Properties="DSN=Excel Files; DBQ=<Assume_Location>FILE_NAME.xls;
DriverId=1046;MaxBufferSize=2048;PageTimeout=5;""
In this example the filename is of extension ".xls" but this can be anything e.g. xlsx, dbf, mdb, accdb etc. . We don't have control over how the connection string is generated
Data Source (i.e. DBQ in this example) may be different for different connection strings e.g. Network Address, SourceDB, Server, Hostname etc.
This will work assuming:
The file name does not contain ;
There is a period between the filename and the extension
There is a ; before the filename
There is a ; after the extension
string pattern = #";(?<filename>[^;]*)[.]{1,1}.*;";
string fileName = Regex.Match(connectionString, pattern).Groups["filename"].Value;
Or if this <Assume_Location> is before the file name rather than ; then you can use this for the pattern:
string pattern = #"<Assume_Location>(?<filename>[^;]*)[.]{1,1}.*;";
Edit 1 - In response to comment.
One of these should work if you need the extension as well:
string pattern = #";(?<filename>[^;]*[.]{1,1}[^;]*);";
string pattern = #"<Assume_Location>(?<filename>[^;]*[.]{1,1}[^;]*);";
Edit 2 - In response to more comments.
This should absolutely work (unless it does not, then I will edit this to tone down the confidence level).
string pattern = #";[^=]*=<[^>]*>(?<filename>[^;]*[.][^;]*);";
or this if > and < is not replaced with angle brackets:
string pattern = #";[^=]*=<.*>(?<filename>[^;]*[.][^;]*);";
Well, I am not 100% sure, but it seems like the file is the only thing that is not assigned, is it? Then you can use the following (not tested):
(;|^)(?<File>[^=]+)(;|$)
If the filename always starts with <Assume_Location> then you can:
public static string GetAssumeLocation(string connectionString)
{
const string assumeLocation = "<Assume_Location>";
var builder1 = new DbConnectionStringBuilder();
builder1.ConnectionString = connectionString;
object extended;
if (builder1.TryGetValue("Extended Properties", out extended) && extended is string)
{
var builder2 = new DbConnectionStringBuilder();
builder2.ConnectionString = (string)extended;
foreach (KeyValuePair<string, object> kv in builder2)
{
var value = kv.Value as string;
if (value != null && value.StartsWith(assumeLocation))
{
return Path.GetExtension(value.Substring(assumeLocation.Length));
}
}
}
return null;
}
Note that I'm using the DbConnectionStringBuilder to "split" the connection string, and I'm looking only in the Extended Properties.

Rename file using regular expression

What I want to do is rename all file in a particular folder, such that if a filename contains any digit in it, it is removed.
say, if a filename is
someFileName.someExtension it remains the same, but if a file is like this,
03 - Rocketman Elton John it should be renamed to Rocketman Elton John (I did the part to remove the -), another example, if the filename is 15-Trey Songz - Unfortunate (Prod. by Noah 40 Shebib) it should be renamed to Trey Songz Unfortunate (Prod. by Noah Shebib) (again I can remove -). The user is asked to select the folder like this
private void txtFolder_MouseDown(object sender, MouseEventArgs e)
{
FolderBrowserDialog fd = new FolderBrowserDialog();
fd.RootFolder = Environment.SpecialFolder.Desktop;
fd.ShowNewFolderButton = true;
if (fd.ShowDialog() == DialogResult.OK)
{
txtFolder.Text = fd.SelectedPath;
}
}
Also, it renaming starts like this
private void btnGo_Click(object sender, EventArgs e)
{
StartRenaming(txtFolder.Text);
}
and
private void StartRenaming(string FolderName)
{
string[] files = Directory.GetFiles(FolderName);
foreach (string file in files)
RenameFile(file);
}
Now in rename file, I need the function, the regular expression that will remove any number(s) in file.
Its is implemented as
private void RenameFile(string FileName)
{
string fileName = Path.GetFileNameWithoutExtension(FileName);
/* here the function goes that will find numbers in filename using regular experssion and replace them */
}
so what I can do is, I can use something like
1 var matches = Regex.Matches(fileName, #"\d+");
2
3 if (matches.Count == 0)
4 return null;
5
6 // start the loop
7 foreach(var match in matches)
8 {
9 fileName = fileName.Replace(match, ""); /* or fileName.Replace(match.ToString(), ""), whatever be the case */
10 }
11 File.Move(FileName, Path.Combine(Path.GetDirectoryName(FileName), fileName));
12 return;
But I don't think that's the right way to do it? Is there any better option to do this? or is this the best (and only option) to do this? Also, is there anything like IN in String.Replace? Say in sql I can use IN in a select command and specify a bunch of where conditions, but is there something like this with String.Replace so that I don't have to run the loop I ran from line 7 to 10? Are there any other better options?
ps: about that regex, I posted a question Regular Expression for numbers? (apparently I wasn't clear enough) and from that I got my regex, if you think someother regex would do better please tell me, also if you need any other information please let me know...
You can try Regex.Replace to remove digits, ie:
Regex.Replace(fileName, #"\d", "");
In the off chance that you are merely looking to simply rename the files and you thought that creating your own program would be the best way - I would recommend PFrank as a standalone tool (especially if you understand regex already)
If you do desire this and if you do take my suggestion (and since it's not the simplest and clearest interface), you would use \d+(\s?-)? for the match expression (in the first column in PFrank), which should match any number of digits, optionally followed by a hyphen and an additional optional whitespace character between the two. You would then have no replacement expression (zero-length string or an empty second column in PFrank). Finally, select the folder containing the files you want renamed and click the scan button; in the dialog that pops up, confirm your results and click the rename button. Sorry if I wasted anyone's time!
For replacing you should look into Regex.Replace which can replace all occurences at once.
Otherwise code look ok (with exception of strange fileName.Replace("match", "") which uses constant string...)
How about this ?
private void StartRenaming(string FolderName)
{
string[] files = Directory.GetFiles(FolderName);
string[] applicableFiles = (from string s in files
where Regex.IsMatch(s, #"(\d+)|(-+)", RegexOptions.None)
select s).ToArray<string>();
foreach (string file in applicableFiles)
RenameFile(file);
}
private void RenameFile(string file)
{
string newFileName = Regex.Replace(file, #"(\d+)|(-+)", "");
File.Move(file, Path.Combine(Path.GetDirectoryName(file), newFileName));
}
StartRenaming method will now limit the number of files to be processed based on Regex match. If the file contains a digit or - then it will be processed, thus optimizing the complete process.
RenameFile replaces digits and - in a string and gives you a newFileName
I am not quite sure about the correctness of File.Move(file, Path.Combine(Path.GetDirectoryName(file), newFileName)); though, but I guess your problem was to avoid the foreach loop, and I think I have provided an appropriate solution.
Please note that I was not able to completely test this, so let me know whether it works for you and if it doesn't I will be happy to help you further.
EDIT : Forgot to mention that file.Replace(#"(\d+)|(-+)", "") will remove digits as well as - from the file string.
EDIT : Corrected file.Replace to Regex.Replace
I prefer to use brackets to select the before and after and then use the $n method to rebuild the string how you want it to be.
"03 - Rocketman Elton John" -Replace '^([^-]*) - ([^-]*)', '$1 $2'

Regex required for renaming file in C#

I need a regex for renaming file in c#. My file name is 22px-Flag_Of_Sweden.svg.png. I want it to rename as sweden.png.
So for that I need regex. Please help me.
I have various files more than 300+ like below:
22px-Flag_Of_Sweden.svg.png - should become sweden.png
13px-Flag_Of_UnitedStates.svg.png - unitedstates.png
17px-Flag_Of_India.svg.png - india.png
22px-Flag_Of_Ghana.svg.png - ghana.png
These are actually flags of country. I want to extract Countryname.Fileextension. Thats all.
var fileNames = new [] {
"22px-Flag_Of_Sweden.svg.png"
,"13px-Flag_Of_UnitedStates.svg.png"
,"17px-Flag_Of_India.svg.png"
,"22px-Flag_Of_Ghana.svg.png"
,"asd.png"
};
var regEx = new Regex(#"^.+Flag_Of_(?<country>.+)\.svg\.png$");
foreach ( var fileName in fileNames )
{
if ( regEx.IsMatch(fileName))
{
var newFileName = regEx.Replace(fileName,"${country}.png").ToLower();
//File.Save(Path.Combine(root, newFileName));
}
}
I am not exactly sure how this would look in c# (although the regex is important and not the language), but in Java this would look like this:
String input = "22px-Flag_Of_Sweden.svg.png";
Pattern p = Pattern.compile(".+_(.+?)\\..+?(\\..+?)$");
Matcher m = p.matcher(input);
System.out.println(m.matches());
System.out.println(m.group(1).toLowerCase() + m.group(2));
Where the relevant for you is this part :
".+_(.+?)\\..+?(\\..+?)$"
Just concat the two groups.
I wish I knew a bit of C# right now :)
Cheers Eugene.
This will return country in the first capture group: ([a-zA-Z]+)\.svg\.png$
I don't know c# but the regex could be:
^.+_(\pL+)\.svg\.png
and the replace part is : $1.png

Path functions for URL

I want to use functions of Path class (GetDirectoryName, GetFileName, Combine,etc.) with paths in URL format with slash (/).
Example of my path:
"xxx://server/folder1/folder2/file"
I tried to do the job with Path functions and in the end just replaced the separator.
I've found that the GetDirectoryName function does not correctly replace the slashes:
Path.GetDirectoryName(#"xxx://server/folder/file") -> #"xxx:\server\folder"
Like you see one slash is lost.
How can I cause the Path functions to use the 'alternative' separator?
Can I use another class with the same functionality?
I'm afraid GetDirectoryName, GetFileName, Combine,etc. use Path.DirectorySeparatorChar in the definition and you want Path.AltDirectorySeparatorChar.
And since Path is a sealed class, I think the only way to go about is string replacement.You can replace Path.DirectorySeparatorChar('\') with Path.AltDirectorySeparatorChar('/') and Path.VolumeSeparatorChar(':') with ":/"
For GetDirectoryName(), you can use
pageRoot = uri.Remove(uri.LastIndexOf('/') + 1);
Have you considered using a combination of System.Uri, System.UriBuilder, and (if necessary) custom System.UriParser subclass(es)?
If the URI is a local file URI of the form file://whatever then you can call string path = new Uri(whatever).LocalPath and call the Path methods on it. If you cannot guarantee the Uri is to a local path, you cannot guarantee components of the Uri correspond to machines, folders, files, extensions, use directories, separator characters, or anything else.
Long time after...I was looking for a solution and found this topic, so i decided to make my (very simple) code
string dirRootUpdate = string.Empty;
string fileNameupdate = string.Empty;
string pathToGetUpdate = string.Empty;
string[] _f = Properties.Settings.Default.AutoUpdateServerUrl.Split('/');
for (int i = 0; i < _f.Count() - 1; i++)
{
dirRootUpdate += _f[i];
if (i == 0) // is the first one
{
dirRootUpdate += "/";
}
else if (i != _f.Count() - 2) // not the last one ?
{
dirRootUpdate += "/";
}
}
fileNameupdate = _f[_f.Count() - 1];
the setting "Properties.Settings.Default.AutoUpdateServerUrl" contains the string to be verified
Works fine, may require some refination to look better.
Hope could help someone

Categories