Trim off last directory/folder without using GetParent() - c#

I am trying to emulate what "cd .." does, but without using Getparent().
input: /var/mobile/Documents/
actual output: /var/mobile/Documents/
desired output: /var/mobile/
public ArrayList JumpUpDirectory()
{
ArrayList directoryListing = new ArrayList();
StringBuilder storedPath = new StringBuilder();
foreach (var directories in storedPreviousDirectory.Split('/'))
{
storedPath.Append(directories + "/");
}
storedPath.Replace("//", "/");
directoryListing = iPhoneFileSystemBrowse(storedPreviousDirectory);
return directoryListing;
}

Try this:
string input = "/var/mobile/Documents/";
var parts = input.Split(new []{'/'}, StringSplitOptions.RemoveEmptyEntries).ToList();
parts.RemoveAt(parts.Count - 1);
string output = string.Concat("/", string.Join("/", parts), "/");

Related

How to split by multiple strings in C#

My Question consists of how might i split a string like this:
""List of devices attached\r\n9887bc314\tdevice\r\n12n1n2nj1jn2
\tdevice\r\n\r\n"
Into:
[n9887bc314,n12n1n2nj1jn2]
I have tried this but it throws the error "Argument 1: cannot convert from 'string' to 'char'"
string[] delimiterChars = new string[] {"\\","r","n","tdevice"};
string y = output.Substring(z+1);
string[] words;
words = y.Split(delimiterChars, StringSplitOptions.None);
I'm wondering if i'm doing something wrong because i'm quite new at c#.
Thanks A Lot
First of all String.Split accept strings[] as delimiters
Here is my code, hope it will helps:
string input = "List of devices attached\r\n9887bc314\tdevice\r\n12n1n2nj1jn2\tdevice\r\n\r\n";
string[] delimiterChars = {
"\r\n",
"\tdevice",
"List of devices attached"
};
var words = input.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
foreach (var word in words)
{
Console.WriteLine(word);
}
Split the whole string by the word device and then remove the tabs and new lines from them. Here is how:
var wholeString = "List of devices attached\r\n9887bc314\tdevice\r\n12n1n2nj1jn2\tdevice\r\n\r\n";
var splits = wholeString.Split(new[] { "device" }, StringSplitOptions.RemoveEmptyEntries);
var device1 = splits[1].Substring(splits[1].IndexOf("\n") + 1).Replace("\t", "");
var device2 = splits[2].Substring(splits[2].IndexOf("\n") + 1).Replace("\t", "");
I've been doing a first aproach and it works, it might help:
I splited the input looking for "/tdevice" and then cleaned everyting before /r/n including the /r/n itself. It did the job and should work with your adb output.
EDIT:
I've refactored my answer to consider #LANimal answer (split using all delimiters) and I tried this code and works. (note the # usage)
static void Main(string[] args)
{
var inputString = #"List of devices attached\r\n9887bc314\tdevice\r\n12n1n2nj1jn2\tdevice\r\n\r\n";
string[] delimiters = {
#"\r\n",
#"\tdevice",
#"List of devices attached"
};
var chunks = inputString.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
string result = "[";
for (int i = 0; i < chunks.Length; i++)
{
result += chunks[i] + ",";
}
result = result.Remove(result.Length - 1);
result += "]";
Console.WriteLine(result);
Console.ReadLine();
}
I hope it helps,
Juan
You could do:
string str = #"List of devices attached\r\n9887bc314\tdevice\r\n12n1n2nj1jn2\tdevice\r\n\r\n";
string[] lines = str.Split(new[] { #"\r\n" }, StringSplitOptions.None);
string firstDevice = lines[1].Replace(#"\tdevice", "");
string secondDevice = lines[2].Replace(#"\tdevice", "");

C# WebClient.DownloadFile to specific path

Hi i'm trying to download a png file and place it in a custom location and i have tried adding to the line but wc.DownloadFile does not allow 3 arguments. does anyone have a suggestion? (rookie programmer)
if i change wc.DownloadFile to wc.DownloadFileAsync it gives me an error on y[2]
string lookat = args[0];
string[] exploded = lookat.Split('/');
WebClient wc = new WebClient();
wc.Proxy = new WebProxy();
string content = wc.DownloadString(args[0]);
Regex rx = new Regex("data-id=\"(.*)\">");
MatchCollection matches = rx.Matches(content);
string uri = "http://" + exploded[2] + "/v2/photo/=";
string id = matches[0].ToString().Replace("\"", "").Replace(">", "").Replace("data-id=", "");
content = wc.DownloadString(uri + id);
string[] res = content.Split(new string[] { "filetobedownloaded_" }, StringSplitOptions.None);
foreach (string s in res)
{
if (s.Contains(".png"))
{
string[] y = s.Replace("\\", "").Split('"');
wc.DownloadFile(y[2], "filetobedownloaded_" + y[0].Replace("_png", ".jpg"));
}
}
The DownloadFileAsync accepts Uri and not string so you should convert your download link to Uri like this:
wc.DownloadFileAsync(new Uri(y[2]), "C:\\" + "filetobedownloaded_" + y[0].Replace("_png", ".jpg"));

Checking for and removing any characters in a string

I am wondering what would be the best way to specify an array of characters like,
{
}
[
]
and then check a string for these and if they are there, to completely remove them.
if (compiler.Parser.GetErrors().Count == 0)
{
AstNode root = compiler.Parse(phrase.ToLower());
if (compiler.Parser.GetErrors().Count == 0)
{
try
{
fTextSearch = SearchGrammar.ConvertQuery(root, SearchGrammar.TermType.Inflectional);
}
catch
{
fTextSearch = phrase;
}
}
else
{
fTextSearch = phrase;
}
}
else
{
fTextSearch = phrase;
}
string[] brackets = brackets = new string[]
{
"{",
"}",
"[",
"]"
};
string[] errorChars = errorChars = new string[]
{
"'",
"&"
};
StringBuilder sb = new StringBuilder();
string[] splitString = fTextSearch.Split(errorChars, StringSplitOptions.None);
int numNewCharactersAdded = 0;
foreach (string itm in splitString)
{
sb.Append(itm); //append string
if (fTextSearch.Length > (sb.Length - numNewCharactersAdded))
{
sb.Append(fTextSearch[sb.Length - numNewCharactersAdded]); //append splitting character
sb.Append(fTextSearch[sb.Length - numNewCharactersAdded - 1]); //append it again
numNewCharactersAdded++;
}
}
string newString = sb.ToString();
A regular expression can do this far more easily:
var result = Regex.Replace(input, #"[[\]()]", "");
Using a character set ([...]) to match anyone of the characters in it and replace with nothing. Regex.Replace will replace all matches.
Another concise way is using Enumerable.Except to get the set difference of the Chars(assuming brackets are chars):
String newString = new String(oldString.Except(brackets).ToArray());
string str = "faslkjnro(fjrmn){ferqwe}{{";
char[] separators = new []{'[', ']','{','}' };
var sb = new StringBuilder();
foreach (var c in str)
{
if (!separators.Contains(c))
{
sb.Append(c);
}
}
return sb.ToString();
How about this:
string myString = "a12{drr[ferr]vgb}rtg";
myString = myString.Replace("[", "").Replace("{", "").Replace("]", "").Replace("}", "");
You end up with:
a12drrferrvgbrtg
I don't know if I understand your problem, but you can solve your problem with this:
string toRemove = "{}[]";
string result = your_string_to_be_searched;
foreach(char c in toRemove)
result = result.Replace(c.ToString(), "");
or with an extension method
static class Extensions
{
public static string RemoveAll(this string src, string chars)
{
foreach(char c in chars)
src= src.Replace(c.ToString(), "");
return src;
}
}
With this you can use string result = your_string_to_be_searched.RemoveAll("{}[]");
string charsToRemove = #"[]{}";
string pattern = string.Format("[{0}]", Regex.Escape(charsToRemove));
var result = Regex.Replace(input, pattern, "");
The primary advantage of this over some of the other similar answers is that you aren't bothered with determining which characters need to be escaped in RegEx; you can let the library take care of that for you.
You can do this in a pretty compact fashion like this:
string s = "ab{c[d]}";
char[] ca = new char[] {'{', '}', '[', ']'};
Array.ForEach(ca, e => s = s.Replace(e.ToString(), ""));
Or this:
StringBuilder s = new StringBuilder("ab{c[d]}");
char[] ca = new char[] {'{', '}', '[', ']'};
Array.ForEach(ca, e => s.Replace(e.ToString(), ""));
Taken from this answer: https://stackoverflow.com/a/12800424/1498669
Just use .Split() with the char[] of your desired removeables and recapture it with .Join() or .Concat()
char[] delChars = "[]{}<>()".ToCharArray();
string input = "some (crazy) string with brac[et]s in{si}de";
string output = string.Join(string.Empty, input.Split(delChars));
//or
string output = string.Concat(input.Split(delChars));
References:
https://learn.microsoft.com/en-us/dotnet/csharp/how-to/parse-strings-using-split
https://learn.microsoft.com/en-us/dotnet/csharp/how-to/concatenate-multiple-strings#code-try-4

Trouble passing a parameter to a class in C#

I'm having a bit of trouble passing this parameter to a class i have. Does anybody have any ideas?
Class 1's code:
public void DriveRecursion(string retPath)
{
//recurse through files. Let user press 'ok' to move onto next step
// string[] files = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
string pattern = " *[\\~#%&*{}/<>?|\"-]+ *";
//string replacement = "";
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> filePath = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
if (regEx.IsMatch(fileNames))
{
string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
filePath.Add(fileNames);
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = fileNameOnly;
dataGridView1.Rows.Add(dgr);
\\I want to pass fileNames to my FileCleanup Method
\\I tried this:
\\SanitizeFileNames sf = new SanitizeFileNames();
\\sf.Add(fileNames); <-- this always gets an error..plus it is not an action i could find in intellisense
}
else
{
continue;
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
Class 2's code:
public class SanitizeFileNames
{
public void FileCleanup(string fileNames)
{
string regPattern = " *[\\~#%&*{}/<>?|\"-]+ *";
string replacement = "";
Regex regExPattern = new Regex(regPattern);
}
What i want to do in SanitizeFileNames is do a foreach through the FileNames & FilePath and replace invalid chars (as defined in my Regex pattern). So, something along the lines of this:
using (StreamWriter sw = new StreamWriter(#"S:\File_Renames.txt"))
{
//Sanitize and remove invalid chars
foreach (string Files2 in filePath)
{
try
{
string filenameOnly = Path.GetFileName(Files2);
string pathOnly = Path.GetDirectoryName(Files2);
string sanitizedFilename = regEx.Replace(filenameOnly, replacement);
string sanitized = Path.Combine(pathOnly, sanitizedFilename);
sw.Write(sanitized + "\r\n");
System.IO.File.Move(Files2, sanitized);
}
//error logging
catch(Exception ex)
{
StreamWriter sw2 = new StreamWriter(#"S:\Error_Log.txt");
sw2.Write("ERROR LOG");
sw2.WriteLine(DateTime.Now.ToString() + ex + "\r\n");
sw2.Flush();
sw2.Close();
}
}
}
However, I'm having trouble passing the fileNames into my SanitizeFileNames class. Can anybody help me?
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
if (regEx.IsMatch(fileNames))
{
string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
filePath.Add(fileNames);
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = fileNameOnly;
dataGridView1.Rows.Add(dgr);
new SanitizeFileNames().FileCleanup(fileNames);
}
else
{
continue;
}
}
}
I suppose you want to pass a dirty name to the FileCleanup function and get a clean out. Here is how you can do that :
public String FileCleanup(string fileNames)
{
string regPattern = " *[\\~#%&*{}/<>?|\"-]+ *";
string replacement = "";
Regex regExPattern = new Regex(regPattern);
...
return cleanName;
}
and use it in your code like this:
String cleanName = new SanitizeFileNames().FileCleanup(fileNames);
where you put the comment.
You can create a third class static class and add static variable called files “public static List<string> Files= new List<string>()” as example.
When you create the files add the same files to the static variable.
When you clean the files loop throw the static variable, and at the end clear it.
The parameter type should be an enumerable collection of some sort: a list or an array would do. Also, strings are immutable so you could return a list of cleaned up filenames:
public class SanitizeFilenames
{
public List<string> FileCleanUp(IEnumerable<string> filenames)
{
var cleanedFileNames = new List<string>();
var invalidChars = Path.GetInvalidFileNameChars();
foreach(string file in filenames)
{
if(file.IndexOfAny(invalidChars) != -1)
{
// clean the file name and add it to the cleanedFileNames list
}
else
{
// nothing to clean here
cleanedFileNames.Add(file);
}
}
return cleanedFileNames;
}
}

C# complicated regex

Hey guys, thanks for all the help that you can provide. I need a little bit of regex help thats far beyond my knowledge.
I have a listbox with a file name in it, example 3123~101, a delimited file that has 1 line of text in it. I need to Regex everything after the last "\" before the last "-" in the text file. The ending will could contain a prefix then ###{####-004587}.txt The ~ formula is {### + ~# -1.
File name:
3123~101
So Example 1:
3123|X:directory\Path\Directory|Pre0{0442-0500}.txt
Result:
X:\directory\Path\Directory\Pre00542.txt
File name:
3123~101
So Example 1:
3123|X:directory\Path\Directory|0{0442-0500}.txt
Result:
X:\directory\Path\Directory\00542.txt
According your example I've created the following regexp:
\|(.)(.*)\|(.*)\{\d{2}(\d{2})\-(\d{2}).*(\..*)
The result should be as following:
group1 + "\\" + group2 + "\\" + group3 + group5 + group4 + group6
If you ain't satisfied, you can always give it a spin yourself here.
EDIT:
After remembering me about named groups:
\|(?<drive>.)(?<path>.*)\|(?<prefix>.*)\{\d{2}(?<number2>\d{2})\-(?<number1>\d{2}).*(?<extension>\..*)
drive + "\\" + path + "\\" + prefix + number1 + number2 + extension
public static string AdjustPath(string filename, string line)
{
int tilde = GetTilde(filename);
string[] fields = Regex.Split(line, #"\|");
var addbackslash = new MatchEvaluator(
m => m.Groups[1].Value + "\\" + m.Groups[2].Value);
string dir = Regex.Replace(fields[1], #"^([A-Z]:)([^\\])", addbackslash);
var addtilde = new MatchEvaluator(
m => (tilde + Int32.Parse(m.Groups[1].Value) - 1).
ToString().
PadLeft(m.Groups[1].Value.Length, '0'));
return Path.Combine(dir, Regex.Replace(fields[2], #"\{(\d+)-.+}", addtilde));
}
private static int GetTilde(string filename)
{
Match m = Regex.Match(filename, #"^.+~(\d+)$");
if (!m.Success)
throw new ArgumentException("Invalid filename", "filename");
return Int32.Parse(m.Groups[1].Value);
}
Call AdjustPath as in the following:
public static void Main(string[] args)
{
Console.WriteLine(AdjustPath("3123~101", #"3123|X:directory\Path\Directory|Pre0{0442-0500}.txt"));
Console.WriteLine(AdjustPath("3123~101", #"3123|X:directory\Path\Directory|0{0442-0500}.txt"));
}
Output:
X:\directory\Path\Directory\Pre00542.txt
X:\directory\Path\Directory\00542.txt
If instead you want to write the output to a file, use
public static void WriteAdjustedPaths(string inpath, string outpath)
{
using (var w = new StreamWriter(outpath))
{
var r = new StreamReader(inpath);
string line;
while ((line = r.ReadLine()) != null)
w.WriteLine("{0}", AdjustPath(inpath, line));
}
}
You might call it with
WriteAdjustedPaths("3123~101", "output.txt");
If you want a List<String> instead
public static List<String> AdjustedPaths(string inpath)
{
var paths = new List<String>();
var r = new StreamReader(inpath);
string line;
while ((line = r.ReadLine()) != null)
paths.Add(AdjustPath(inpath, line));
return paths;
}
To avoid repeated logic, we should define WriteAdjustedPaths in terms of the new function:
public static void WriteAdjustedPaths(string inpath, string outpath)
{
using (var w = new StreamWriter(outpath))
{
foreach (var p in AdjustedPaths(inpath))
w.WriteLine("{0}", p);
}
}
The syntax could be streamlined with Linq. See C# File Handling.
A slight variation on gbacon's answer that will also work in older versions of .Net:
static void Main(string[] args)
{
Console.WriteLine(Adjust("3123~101", #"3123|X:directory\Path\Directory|Pre0{0442-0500}.txt"));
Console.WriteLine(Adjust("3123~101", #"3123|X:directory\Path\Directory|0{0442-0500}.txt"));
}
private static string Adjust(string name, string file)
{
Regex nameParse = new Regex(#"\d*~(?<value>\d*)");
Regex fileParse = new Regex(#"\d*\|(?<drive>[A-Za-z]):(?<path>[^\|]*)\|(?<prefix>[^{]*){(?<code>\d*)");
Match nameMatch = nameParse.Match(name);
Match fileMatch = fileParse.Match(file);
int value = Convert.ToInt32(nameMatch.Groups["value"].Value);
int code = Convert.ToInt32(fileMatch.Groups["code"].Value);
code = code + value - 1;
string drive = fileMatch.Groups["drive"].Value;
string path = fileMatch.Groups["path"].Value;
string prefix = fileMatch.Groups["prefix"].Value;
string result = string.Format(#"{0}:\{1}\{2}{3:0000}.txt",
drive,
path,
prefix,
code);
return result;
}
You don't seem to be very clear in your examples.
That said,
/.*\\(.*)-[^-]*$/
will capture all text between the last backslash and the last hyphen in whatever it's matched against.

Categories

Resources