Getting rid of *consecutive* periods in a filename - c#

I was wondering how I'd get rid of periods in a filename if i have a filename like:
Test....1.txt to look like Test 1.txt ? I do NOT want files like : 1.0.1 Test.txt to be touched. Only files with consecutive periods should be replaced with a space. Any ideas?
This is my current code but as you can see, it replaces every period aside from periods in extension names:
public void DoublepCleanUp(List<string> doublepFiles)
{
Regex regExPattern2 = new Regex(#"\s{2,}");
Regex regExPattern4 = new Regex(#"\.+");
Regex regExPattern3 = new Regex(#"\.(?=.*\.)");
string replace = " ";
List<string> doublep = new List<string>();
var filesCount = new Dictionary<string, int>();
try
{
foreach (string invalidFiles in doublepFiles)
{
string fileOnly = System.IO.Path.GetFileName(invalidFiles);
string pathOnly = System.IO.Path.GetDirectoryName(fileOnly);
if (!System.IO.File.Exists(fileOnly))
{
string filewithDoublePName = System.IO.Path.GetFileName(invalidFiles);
string doublepPath = System.IO.Path.GetDirectoryName(invalidFiles);
string name = System.IO.Path.GetFileNameWithoutExtension(invalidFiles);
//string newName = name.Replace(".", " ");
string newName = regExPattern4.Replace(name, replace);
string newName2 = regExPattern2.Replace(newName, replace);
string filesDir = System.IO.Path.GetDirectoryName(invalidFiles);
string fileExt = System.IO.Path.GetExtension(invalidFiles);
string fileWithExt = newName2 + fileExt;
string newPath = System.IO.Path.Combine(filesDir, fileWithExt);
System.IO.File.Move(invalidFiles, newPath);
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = doublepPath;
clean.Cells[1].Value = filewithDoublePName;
clean.Cells[2].Value = fileWithExt;
dataGridView1.Rows.Add(clean);
}
else
{
if (filesCount.ContainsKey(fileOnly))
{
filesCount[fileOnly]++;
}
else
{
filesCount.Add(fileOnly, 1);
string newFileName = String.Format("{0}{1}{2}",
System.IO.Path.GetFileNameWithoutExtension(fileOnly),
filesCount[fileOnly].ToString(),
System.IO.Path.GetExtension(fileOnly));
string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fileOnly), newFileName);
System.IO.File.Move(fileOnly, newFilePath);
DataGridViewRow clean = new DataGridViewRow();
clean.CreateCells(dataGridView1);
clean.Cells[0].Value = pathOnly;
clean.Cells[1].Value = fileOnly;
clean.Cells[2].Value = newFileName;
dataGridView1.Rows.Add(clean);
}
}
}
}
catch(Exception e)
{
//throw;
StreamWriter doublepcleanup = new StreamWriter(#"G:\DoublePeriodCleanup_Errors.txt");
doublepcleanup.Write("Double Period Error: " + e + "\r\n");
doublepcleanup.Close();
}
}

string name = "Text...1.txt";
Regex r = new Regex("[.][.]+");
string result = r.Replace(name, " ");

Well, to do that with a string:
string st = "asdf..asdf...asfd...asdf.asf.asdf.s.s";
Regex r = new Regex("\\.\\.+");
st = r.Replace(st, " ");
This will replace any instance of 2 or more '.'s with a space.
I would throw this into a method:
public static string StringReplace(string original,
string regexMatch, string replacement) {
Regex r = new Regex(regexMatch);
return r.Replace(original, replacement);
}

How about this?
string newFileName = String.Join(".", fileName.Split('.').Select(p => !String.IsNullOrEmpty(p) ? p : " ").ToArray())

Why not use something like this?
string newName = name;
while (newName.IndexOf("..") != -1)
newName = newName.Replace("..", " ");

static string CleanUpPeriods(string filename)
{
StringBuilder sb = new StringBuilder();
if (filename.Length > 0) sb.Append(filename[0]);
for (int i = 1; i < filename.Length; i++)
{
char last = filename[i - 1];
char current = filename[i];
if (current != '.' || last != '.') sb.Append(current);
}
return sb.ToString();
}

You could use use regular expressions, something like this
string fileName = new Regex(#"[.][.]+").Replace(oldFileName, "");

Continuing from dark_charlie's solution, isn't
string newName = name;
while (newName.IndexOf("..") != -1)
newName = newName.Replace("..", ".");
enough?

I have tested this code on a number of cases, and it appears to exhibit the requested behavior.
private static string RemoveExcessPeriods(string text)
{
if (string.IsNullOrEmpty(text))
return string.Empty;
// If there are no consecutive periods, then just get out of here.
if (!text.Contains(".."))
return text;
// To keep things simple, let's separate the file name from its extension.
string extension = Path.GetExtension(text);
string fileName = Path.GetFileNameWithoutExtension(text);
StringBuilder result = new StringBuilder(text.Length);
bool lastCharacterWasPeriod = false;
bool thisCharacterIsPeriod = fileName.Length > 0 && fileName[0] == '.';
bool nextCharacterIsPeriod;
for (int index = 0; index < fileName.Length; index++)
{
// Includes both the extension separator and other periods.
nextCharacterIsPeriod = fileName.Length == index + 1 || fileName[index + 1] == '.';
if (!thisCharacterIsPeriod)
result.Append(fileName[index]);
else if (thisCharacterIsPeriod && !lastCharacterWasPeriod && !nextCharacterIsPeriod)
result.Append('.');
else if (thisCharacterIsPeriod && !lastCharacterWasPeriod)
result.Append(' ');
lastCharacterWasPeriod = thisCharacterIsPeriod;
thisCharacterIsPeriod = nextCharacterIsPeriod;
}
return result.ToString() + extension;
}
I just made a change to handle some edge cases. Here are some test results for this version.
"Test....1.txt" => "Test 1.txt"
"1.0.1..Test.txt" => "1.0.1 Test.txt"
"Test......jpg" => "Test .jpg"
"Test.....jpg" => "Test .jpg"
"one.pic.jpg" => "one.pic.jpg"
"one..pic.jpg" => "one pic.jpg"
"one..two..three.pic.jpg" => "one two three.pic.jpg"
"one...two..three.pic.jpg" => "one two three.pic.jpg"
"one..two..three.pic..jpg" => "one two three.pic .jpg"
"one..two..three..pic.jpg" => "one two three pic.jpg"
"one..two..three...pic...jpg" => "one two three pic .jpg"

Combining some other answers...
static string CleanUpPeriods(string filename)
{
string extension = Path.GetExtension(filename);
string name = Path.GetFileNameWithoutExtension(filename);
Regex regex = new Regex(#"\.\.+");
string s = regex.Replace(name, " ").Trim();
if (s.EndsWith(".")) s = s.Substring(0, s.Length - 1);
return s + extension;
}
Sample Output
"Test........jpg" -> "Test.jpg"
"Test....1.jpg" -> "Test 1.jpg"
"Test 1.0.1.jpg" -> "Test 1.0.1.jpg"
"Test..jpg" -> "Test.jpg"

void ReplaceConsecutive(string src, int lenght, string replace)
{
char last;
int count = 0;
StringBuilder ret = new StringBuilder();
StringBuilder add = new StringBuilder();
foreach (char now in src)
{
if (now == last)
{
add.Append(now);
if (count > lenght)
{
ret.Append(replace);
add = new StringBuilder();
}
count++;
}
else
{
ret.Append(add);
add = new StringBuilder();
count = 0;
ret.Append(now);
}
}
return ret.ToString();
}
Untested, but this should work.
src is the string you want to check for consecutives, lenght is the number of equal chars followed by each other until they get replaced with replace.
This is AFAIK also possible in Regex, but I'm not that good with Regex's that I could do this.

Related

How to split path to set of Path

I have one path variable like 'Customer\\Calls\\A1\\A2\\A3\\A4'.From this i want split it into an array like
'Customer'
'Customer\Calls'
'Customer\Calls\A1'
'Customer\Calls\A1\A2'
'Customer\Calls\A1\A2\A3'
'Customer\Calls\A1\A2\A3\A4'
If we do it like
string[] directories = currentFolderPath.Split(Path.DirectorySeparatorChar);
we will get a set of folder,but it will not get in above structure
Can anyone suggest a better approach
Get parent directory until you get to the root
if it's an absolute path
private static IEnumerable<string> SplitPath(string path){
do{
yield return path;
path=Path.GetDirectoryName(path);
} while(path!=null);
}
if it is a relative path
private static IEnumerable<string> SplitRelativePath(string path){
do{
yield return path;
var lastIndex=path.LastIndexOf('\\');
if(lastIndex==-1)
yield break;
path=path.Substring(0, lastIndex);
} while(path!=null);
}
//usage
SplitRelativePath(#"Customer\Calls\A1\A2\A3\A4");
/* result:
C:\Customer\Calls\A1\A2\A3\A4
C:\Customer\Calls\A1\A2\A3
C:\Customer\Calls\A1\A2
C:\Customer\Calls\A1
C:\Customer\Calls
C:\Customer
C:\ *
string path = #"Customer\Calls\A1\A2\A3\A4";
var sections = path.Split('\\').ToList();
var result = Enumerable.Range(0, sections.Count)
.Select(index => string.Join(#"\", sections.Take(index + 1)))
.ToList();
//Result:
// Customer
// Customer\Calls
// Customer\Calls\A1
// Customer\Calls\A1\A2
// Customer\Calls\A1\A2\A3
// Customer\Calls\A1\A2\A3\A4
It's not really obvious from your post, but if you need to do something with each item in your array, I would probably take this approach:
string path = string.Empty;
"Customer\\Calls\\A1\\A2\\A3\\A4".Split(new Char[] { '\\' }).ToList().ForEach(
part => {
path = Path.Combine(path, part);
// Do stuff!
}
);
// easy and simple try this
string path = #"Customer\Calls\A1\A2\A3\A4";
string[] pathArr = path.Split('\\');
List<string> list = new List<string>();
for (int i = 0; i < pathArr.Length; i++)
{
string temp = pathArr[i];
if (i > 0)
{
temp = list[i - 1].ToString() + #"\" + temp;
}
list.Add(temp);
}
string path = "Customer\\Calls\\A1\\A2\\A3\\A4";
var pathArr = path.Split(new string[] { "\\" }, StringSplitOptions.None);
var pathList = new List<string>();
while (pathArr.Length != pathList.Count)
{
string modifiedPath = "";
for (int i = 0; i < pathArr.Length; i++)
{
modifiedPath = modifiedPath + pathArr[i] + "\\";
if (i == pathList.Count)
{
pathList.Add(modifiedPath);
break;
}
}
}
foreach (var str in pathList)
{
Console.WriteLine(str.Remove(str.Length - 1));
}
Console.ReadKey();

How to get string between start and end character in C#

How to get substring of string like file_{AAA}_{BBB}.xml ?
My Code:
string[] result = Regex.Split(str, "{(.*)}"); result.ToList().ForEach(x => MessageBox.Show(x));
Result :
AAA
BBB
You can try this:
string str = "file_{AAA}_{BBB}.xml";
var regex = new Regex("(?<=\{)[^}]*(?=\})");
var matches = regex.Matches(str);
Super ghetto, I suck at regex and you should probably use Rahul's answer instead, but:
string f = "file_{AAA}_{BBB}.xml";
string o = String.Empty;
while (f.Contains('{') && f.Contains('}'))
{
int openIndex = f.IndexOf('{');
int closeIndex = f.IndexOf('}');
o += f.Substring(openIndex + 1, closeIndex - openIndex - 1) + " ";
f = f.Remove(0, closeIndex + 1);
}
o.Trim();
Console.WriteLine(o);
Will output AAA BBB
Original from Rahul Tripathi, just added removing of {}
string str = "file_{AAA}_{BBB}.xml";
var regex = new Regex("{.*?}");
var matches = regex.Matches(str);
List<string> result = new List<string>();
foreach (var item in matches)
{
result.Add(item.ToString().Replace("{", "").Replace("}", ""));
}
You may follow that:
string filename = string.Format(#"{0}", Path.GetFileName(fileUpload1.PostedFile.FileName));
string filepath = "f:\ClientDocument\" + Path.GetFileName(fileUpload1.PostedFile.FileName);
int fileLength = (fileUpload1.PostedFile.ContentLength) / 1024;

String formatting in C#?

I have some problems to format strings from a List<string>
Here's a picture of the List values:
Now I managed to manipulate some of the values but others not, here's what I used to manipulate:
string prepareStr(string itemToPrepare) {
string first = string.Empty;
string second = string.Empty;
if (itemToPrepare.Contains("\"")) {
first = itemToPrepare.Replace("\"", "");
}
if (first.Contains("-")) {
int beginIndex = first.IndexOf("-");
second = first.Remove(beginIndex, first.Length - beginIndex);
}
return second;
}
Here's a picture of the Result:
I need to get the clear Path without the (-startup , -minimzed , MSRun , double apostrophes).
What am I doing wrong here?
EDIT my updated code:
void getStartUpEntries() {
var startEntries = StartUp.getStartUp();
if (startEntries != null && startEntries.Count != 0) {
for (int i = 0; i < startEntries.Count; i++) {
var splitEntry = startEntries[i].Split(new string[] { "||" }, StringSplitOptions.None);
var str = splitEntry[1];
var match = Regex.Match(str, #"\|\|""(?<path>(?:\""|[^""])*)""");
var finishedPath = match.Groups["path"].ToString();
if (!string.IsNullOrEmpty(finishedPath)) {
if (File.Exists(finishedPath) || Directory.Exists(finishedPath)) {
var _startUpObj = new StartUp(splitEntry[0], finishedPath,
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(finishedPath));
_startUpList.Add(_startUpObj);
}
else {
var _startUpObjNo = new StartUp(splitEntry[0], finishedPath,
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(string.Empty));
_startUpList.Add(_startUpObjNo);
}
}
var _startUpObjLast = new StartUp(splitEntry[0], splitEntry[1],
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(string.Empty));
_startUpList.Add(_startUpObjLast);
}
lstStartUp.ItemsSource = _startUpList.OrderBy(item => item.Name).ToList();
}
You could use a regex to extract the path:
var str = #"0Raptr||""C:\Program Files (x86)\Raptr\raptrstub.exe"" --startup"
var match = Regex.Match(str, #"\|\|""(?<path>(?:\""|[^""])*)""");
Console.WriteLine(match.Groups["path"]);
This will match any (even empty) text (either an escaped quote, or any character which is not a quote) between two quote characters preceeded by two pipe characters.
Similarly, you could simply split on the double quotes as I see that's a repeating occurrence in your examples and take the second item in the split array:
var path = new Regex("\"").Split(s)[1];
This is and update to your logic without using any Regex:
private string prepareStr(string itemToPrepare)
{
string result = null;
string startString = #"\""";
string endString = #"\""";
int startPoint = itemToPrepare.IndexOf(startString);
if (startPoint >= 0)
{
startPoint = startPoint + startString.Length;
int EndPoint = itemToPrepare.IndexOf(endString, startPoint);
if (EndPoint >= 0)
{
result = itemToPrepare.Substring(startPoint, EndPoint - startPoint);
}
}
return result;
}

How to Get Data from index of String

I'm new in c#. and I have some Question...
I have String following this code
string taxNumber = "1222233333445";
I want to get data from This string like that
string a = "1"
string b = "2222"
string c = "33333"
string d = "44"
string e = "5"
Please Tell me about Method for get Data From String.
Thank You Very Much ^^
Use the String.Substring(int index, int length) method
string a = taxNumber.Substring(0, 1);
string b = taxNumber.Substring(1, 4);
// etc
Oh well, the best I can come up with is this:
IEnumerable<string> numbers
= taxNumber.ToCharArray()
.Distinct()
.Select(c => new string(c, taxNumber.Count(t => t == c)));
foreach (string numberGroup in numbers)
{
Console.WriteLine(numberGroup);
}
Outputs:
1
2222
33333
44
5
This can also do , you dont need to fix the no of characters, you can check by changing the no of 1's , 2's etc
string taxNumber = "1222233333445";
string s1 = taxNumber.Substring(taxNumber.IndexOf("1"), ((taxNumber.Length - taxNumber.IndexOf("1")) - (taxNumber.Length - taxNumber.LastIndexOf("1"))) + 1);
string s2 = taxNumber.Substring(taxNumber.IndexOf("2"), ((taxNumber.Length - taxNumber.IndexOf("2")) - (taxNumber.Length - taxNumber.LastIndexOf("2"))) + 1);
string s3 = taxNumber.Substring(taxNumber.IndexOf("3"), ((taxNumber.Length - taxNumber.IndexOf("3")) - (taxNumber.Length - taxNumber.LastIndexOf("3"))) + 1);
You can use Char.IsDigit to identify digits out of string, and may apply further logic as follows:
for (int i=0; i< taxNumber.Length; i++)
{
if (Char.IsDigit(taxNumber[i]))
{
if(taxNumber[i-1]==taxNumber[i])
{
/*Further assign values*/
}
}
Try this Code
string taxNumber = "1222233333445";
char[] aa = taxNumber.ToCharArray();
List<string> finals = new List<string>();
string temp = string.Empty;
for (int i = 0; i < aa.Length; i++)
{
if (i == 0)
{
temp = aa[i].ToString();
}
else
{
if (aa[i].ToString() == aa[i - 1].ToString())
{
temp += aa[i];
}
else
{
if (temp != string.Empty)
{
finals.Add(temp);
temp = aa[i].ToString();
}
}
if (i == aa.Length - 1)
{
if (aa[i].ToString() != aa[i - 1].ToString())
{
temp = aa[i].ToString();
finals.Add(temp);
}
else
{
finals.Add(temp);
}
}
}
}
and check value of finals string list
you may use regex:
string strRegex = #"(1+|2+|3+|4+|5+|6+|7+|8+|9+|0+)";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = #"1222233333445";
return myRegex.Split(strTargetString);

Split a separated string into hierarchy using c# and linq

I have string separated by dot ('.') characters that represents a hierarchy:
string source = "Class1.StructA.StructB.StructC.FieldA";
How can I use C# and linq to split the string into separate strings to show their hierarchy? Such as:
string[] result = new string[]
{
"Class1",
"Class1.StructA",
"Class1.StructA.StructB",
"Class1.StructA.StructB.FieldA"
};
Split the string by the delimiters taking 1...N of the different levels and rejoin the string.
const char DELIMITER = '.';
var source = "Class1.StructA.StructB.StructC.FieldA";
var hierarchy = source.Split(DELIMITER);
var result = Enumerable.Range(1, hierarchy.Length)
.Select(i => String.Join(".", hierarchy.Take(i)))
.ToArray();
Here's a more efficient way to do this without LINQ:
const char DELIMITER = '.';
var source = "Class1.StructA.StructB.StructC.FieldA";
var result = new List<string>();
for (int i = 0; i < source.Length; i++)
{
if (source[i] == DELIMITER)
{
result.Add(source.Substring(0, i));
}
}
result.Add(source); // assuming there is no trailing delimiter
Here is solution that uses aggregation:
const string separator = ".";
const string source = "Class1.StructA.StructB.StructC.FieldA";
// Get the components.
string[] components = source.Split(new [] { separator }, StringSplitOptions.None);
List<string> results = new List<string>();
// Aggregate with saving temporary results.
string lastResult = components.Aggregate((total, next) =>
{
results.Add(total);
return string.Join(separator, total, next);
});
results.Add(lastResult);
Here's a solution completely without LINQ:
public static string[] GetHierarchy(this string path)
{
var res = path.Split('.');
string last = null;
for (int i = 0; i < res.Length; ++i)
{
last = string.Format("{0}{1}{2}", last, last != null ? "." : null, res[i]);
res[i] = last;
}
return res;
}
Shlemiel the painter approach is better than the "super Shlemiel" string.Join in this case.
const char DELIMITER = '.';
string soFar = "";
List<string> result = source.Split(DELIMITER).Select(s =>
{
if (soFar != "") { soFar += DELIMITER; };
soFar += s;
return soFar;
}).ToList();

Categories