My scenario is i have a multiline textbox with multiple values e.g. below:
firstvalue = secondvalue
anothervalue = thisvalue
i am looking for a quick and easy scenario to flip the value e.g. below:
secondvalue = firstvalue
thisvalue = anothervalue
Can you help ?
Thanks
protected void btnSubmit_Click(object sender, EventArgs e)
{
string[] content = txtContent.Text.Split('\n');
string ret = "";
foreach (string s in content)
{
string[] parts = s.Split('=');
if (parts.Count() == 2)
{
ret = ret + string.Format("{0} = {1}\n", parts[1].Trim(), parts[0].Trim());
}
}
lblContentTransformed.Text = "<pre>" + ret + "</pre>";
}
I am guessing that your multiline text box will always have text which is in the format you mentioned - "firstvalue = secondvalue" and "anothervalue = thisvalue". And considering that the text itself doesn't contain any "=". After that it is just string manipulation.
string multiline_text = textBox1.Text;
string[] split = multiline_text.Split(new char[] { '\n' });
foreach (string a in split)
{
int equal = a.IndexOf("=");
//result1 will now hold the first value of your string
string result1 = a.Substring(0, equal);
int result2_start = equal + 1;
int result2_end = a.Length - equal -1 ;
//result1 will now hold the second value of your string
string result2 = a.Substring(result2_start, result2_end);
//Concatenate both to get the reversed string
string result = result2 + " = " + result1;
}
You could also use Regex groups for this. Add two multi line textboxes to the page and a button. For the button's onclick event add:
using System.Text.RegularExpressions;
...
protected void Button1_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
Regex regexObj = new Regex(#"(?<left>\w+)(\W+)(?<right>\w+)");
Match matchResults = regexObj.Match(this.TextBox1.Text);
while (matchResults.Success)
{
string left = matchResults.Groups["left"].Value;
string right = matchResults.Groups["right"].Value;
sb.AppendFormat("{0} = {1}{2}", right, left, Environment.NewLine);
matchResults = matchResults.NextMatch();
}
this.TextBox2.Text = sb.ToString();
}
It gives you a nice way to deal with the left and right hand sides that you are looking to swap, as an alternative to working with substrings and string lengths.
Related
I have the following datatable:
the field "court_case" has a different format and is not compact, the expected format would be: XXXX/XX ("4 digits" / "2 digits" )
For example:
12/13 -> 0012/13
2/1 -> 0002/10
/18 -> 0000/18
45/ -> 0045/00
I.e. complete with leading zeros if it is the case for the first part before the "/" and with leading zeros if it is the case after the "/".
private void bt_showDataTable_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
dataGridView2.DataSource = getDataTable();
}
public DataTable getDataTable()
{
DataTable dtTabla = new DataTable();
try
{
MySqlConnection connection = new MySqlConnection();
connection.ConnectionString = configuracion.conexion;
connection.Open();
string query = "SELECT * FROM CC_T.CONSIGNATION WHERE ACCOUNT IN ('error');"; //query from the image above
MySqlCommand mycmd = new MySqlCommand(query, connection);
mycmd.Connection = connection;
MySqlDataReader reader = mycmd.ExecuteReader();
dtTabla.Load(reader);
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
return dtTabla;
}
// METHOD TO VALIDATE COURT CASE
public static bool Validar_Cc(string CourtCase)
{
int i = 0;
string part1 = "";
string part2 = "";
bool result1 = false;
bool result2 = false;
if (CourtCase.Contains("/"))
{
part1 = CourtCase.Substring(0, CourtCase.IndexOf('/'));
part2 = CourtCase.Substring(CourtCase.IndexOf('/') + 1, CourtCase.Length - CourtCase.IndexOf('/') - 1);
result1 = int.TryParse(part1, out i);
result2 = int.TryParse(part2, out i);
}
if (!result1 || !result2)
{
return false;
}
else return true;
}
with this validation I only check that what comes for court_case is of type integer. but I do not check a validation of the format like: "XXXX/XX".
here I have to pass the method to validate:
private void btnCORRECT_ERROR_COURTCASE_Click(object sender, EventArgs e)
{
string reply = "";
foreach(DataColumn column in dataGridView2.Rows)
{
//
}
}
I know this is wrong but I don't know how to continue. Any help??
Well technically you want to split the string to 2 parts, handle each separately and add it together with added zeroes. Like:
var inputArray = new string[4] { "12/13", "2/1", "/18", "45/" };
var results = new List<string>();
foreach (var str in inputArray)
{
var parts = str.Split(new string[] { "/" }, StringSplitOptions.None);
var result = parts[0].PadLeft(4, '0') + "/" + parts[1].PadLeft(2, '0');
results.Add(result);
}
You can use string.PadLeft method to append leading zeros 0 (or other char) to some string:
static string AddLeadingZeros(string s, int amount)
{
return s.PadLeft(amount, '0');
}
Usage example:
void FixCourtCases()
{
string[] courtCases = new string[]
{
"6906/2",
"9163/2",
"504/",
"3/",
"9/4",
"4311/",
"0/",
"/6",
"193/0",
"0/2",
};
for (int i = 0; i < courtCases.Length; i++)
{
// Split left and right numbers by '/'
string[] courtCase = courtCases[i].Split(new string[] { "/" }, StringSplitOptions.None);
// Add leading zeros to left and right numbers
string fixedLeftNumber = AddLeadingZeros(courtCase[0], 4);
string fixedRightNumber = AddLeadingZeros(courtCase[1], 2)
// Reassign value with fixed one
courtCases[i] = fixedLeftNumber + "/" + fixedRightNumber;
}
}
it will give you that kind of result:
If you just want to check if the input (CourtCase) has the expected format (xxxx/xx) then you could change the Validar_Cc in this way.
public static bool Validar_Cc(string CourtCase)
{
// First check, the string should be 7 character long, if not then fast exit
if (CourtCase.Length != 7)
return false;
// Second check, try to split at /, if you get back an array with more or
// less than two elements then fast exit
string[] parts = CourtCase.Split('/');
if(parts.Length != 2)
return false;
// Now check if the two elements are numbers or not.
// Again fast exit in case of error
if(!Int32.TryParse(parts[0], out int number1))
return false;
if(!Int32.TryParse(parts[1], out int number2))
return false;
// If you reach this point then the data is correct
return true;
}
This example assumes that you consider correct inputs like '0000/00' or '1234/00' or '0000/88'. If this is not the case then one more checks is needed. Just add these lines after the TryParse block
if(number1 == 0 || number2 == 0)
return false;
And you could call the Validar_CC inside the loop over the grid rows
private void btnCORRECT_ERROR_COURTCASE_Click(object sender, EventArgs e)
{
string reply = "";
foreach(DataGridRow row in dataGridView2.Rows)
{
bool result = Validar_Cc(row.Cells["COURT_CASE"].Value.ToString());
.... do whatever you need to do with false/true results
}
}
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;
}
Is there any way to sort lines in winforms richtextbox preserving RTF formatting?
var lines = edit.Lines.OrderBy(s => s);
edit.Lines = lines.ToArray();
do the job fine, but, obviously, loosing any RTF formatting.
I have slightly changed the snippet of TaW:
1. Adding "unique" might break the very first line formatting
2. Besides "\par" tag there is also "\pard"
Here is a snippet (thanks again to TaW!):
private void cmdSort_Click(object sender, EventArgs e)
{
const string PARD = "\\pard";
var pard = Guid.NewGuid().ToString();
var pos1 = edit.Rtf.IndexOf(PARD, StringComparison.Ordinal) + PARD.Length;
if (pos1 < 0) return;
var header = edit.Rtf.Substring(0, pos1);
var body = edit.Rtf.Substring(pos1);
body = body.Replace("\\pard", pard);
var lines = body.Split(new[] { "\\par" }, StringSplitOptions.None);
var lastFormat = "";
var sb = new StringBuilder();
var rtfLines = new SortedList<string, string>();
foreach (var line in lines)
{
var ln = line.Replace(pard, "\\pard");
var temp = ln.Replace("\r\n", "").Trim();
if (temp.Length > 0 && temp[0] != '\\')
{
rtfLines.Add(temp.Trim(), lastFormat + " " + ln);
}
else
{
var pos2 = temp.IndexOf(' ');
if (pos2 < 0)
{
rtfLines.Add(temp.Trim(), ln);
}
else
{
rtfLines.Add(temp.Substring(pos2).Trim(), ln);
lastFormat = temp.Substring(0, pos2);
}
}
}
foreach (var key in rtfLines.Keys.Where(key => key != "}"))
{
sb.Append(rtfLines[key] + "\\par");
}
edit.Rtf = header + sb;
}
Here is a code snippet that seems to work if the file has neither images nor tables embedded..
It uses two RTF boxes. In my tests they sorted alright and kept all formatting intact.
private void button4_Click(object sender, EventArgs e)
{
string unique = Guid.NewGuid().ToString() ;
richTextBox1.SelectionStart = 0;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectedText = unique;
int pos1 = richTextBox1.Rtf.IndexOf(unique);
if (pos1 >= 0)
{
string header = richTextBox1.Rtf.Substring(0, pos1);
string header1 = "";
string header2 = "";
int pos0 = header.LastIndexOf('}') + 1;
if (pos0 > 1) { header1 = header.Substring(0, pos0); header2 = header.Substring(pos0); }
// after the header comes a string of formats to start the document
string[] formats = header2.Split('\\');
string firstFormat = "";
string lastFormat = "";
// we extract a few important character formats (bold, italic, underline, font, color)
// to keep with the first line which will be sorted away
// the lastFormat variable holds the last formatting encountered
// so we can add it to all lines without formatting
// (and of course we are really talking about paragraphs)
foreach (string fmt in formats)
if (fmt[0]=='b' || ("cfiu".IndexOf(fmt[0]) >= 0 && fmt.Substring(0,2)!="uc") )
lastFormat += "\\" + fmt; else firstFormat += "\\" + fmt;
// add the rest to the header
header = header1 + firstFormat;
// now we remove our marker from the body and split it into paragraphs
string body = richTextBox1.Rtf.Substring(pos1);
string[] lines = body.Replace(unique, "").Split(new string[] { "\\par" }, StringSplitOptions.None);
StringBuilder sb = new StringBuilder();
// the soteredlist will contain the unformatted text as key and the formatted one as valaue
SortedList<string, string> rtfLines = new SortedList<string, string>();
foreach (string line in lines)
{
// cleanup
string line_ = line.Replace("\r\n", "").Trim();
if (line_[0] != '\\' ) rtfLines.Add(line_, lastFormat + " " + line);
else
{
int pos2 = line_.IndexOf(' ');
if (pos2 < 0) rtfLines.Add(line_, line);
else
{
rtfLines.Add(line_.Substring(pos2).Trim(), line);
lastFormat = line_.Substring(0, pos2);
}
}
}
foreach (string key in rtfLines.Keys) if (key != "}") sb.Append(rtfLines[key] + "\\par");
richTextBox2.Rtf = header + sb.ToString();
}
Of course this is really q&d and not ready for serious production; but it looks like a start.
EDIT 2: I changed the code to fix a bug with the first line's format and added some comments. This should work a lot better, but is still a hack that must be adapted to the real input files..
RichTextBox has a property Rtf that would keep RTF formatting.
[BrowsableAttribute(false)]
public string Rtf { get; set; }
I have a file. Each line looks like the following:
[00000] 0xD176234F81150469: foo
What I am attempting to do is, if a line contains a certain substring, I want to extract everything on the right of the substring found. For instance, if I were searching for 0xD176234F81150469: in the above line, it would return foo. Each string is of variable length. I am using C#.
As a note, every line in the file looks like the above, having a base-16 number enclosed in square brackets on the left, followed by a hexadecimal hash and a semicolon, and an english string afterwards.
How could I go about this?
Edit
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
Form1 box = new Form1();
if(MessageBox.Show("This process may take a little while as we loop through all the books.", "Confirm?", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
XDocument doc = XDocument.Load(#"C:\Users\****\Desktop\books.xml");
var Titles = doc.Descendants("Title");
List<string> list = new List<string>();
foreach(var Title in Titles)
{
string searchstr = Title.Parent.Name.ToString();
string val = Title.Value;
string has = #"Gameplay/Excel/Books/" + searchstr + #":" + val;
ulong hash = FNV64.GetHash(has);
var hash2 = string.Format("0x{0:X}", hash);
list.Add(val + " (" + hash2 + ")");
// Sample output: "foo (0xD176234F81150469)"
}
string[] books = list.ToArray();
File.WriteAllLines(#"C:\Users\****\Desktop\books.txt", books);
}
else
{
MessageBox.Show("Aborted.", "Aborted");
}
}
I also iterated through every line of the file, adding it to a list<>. I must've accidentally deleted this when trying the suggestions. Also, I am very new to C#. The main thing I am getting stumped on is the matching.
You could use File.ReadLines and this Linq query:
string search = "0xD176234F81150469:";
IEnumerable<String> lines = File.ReadLines(path)
.Select(l => new { Line = l, Index = l.IndexOf(search) })
.Where(x => x.Index > -1)
.Select(x => x.Line.Substring(x.Index + search.Length));
foreach (var line in lines)
Console.WriteLine("Line: " + line);
This works if you don't want to use Linq query.
//"I also iterated through every line of the file, adding it to a list<>." Do this again.
List<string> li = new List<string>()
//However you create this string make sure you include the ":" at the end.
string searchStr = "0xD176234F81150469:";
private void button1_Click(object sender, EventArgs e)
{
foreach (string line in li)
{
string[] words;
words = line.Split(' '); //{"[00000]", "0xD176234F81150469:", "foo"}
if (temp[1] == searchStr)
{
list.Add(temp[2] + " (" + temp[1] + ")");
// Sample output: "foo (0xD176234F81150469)"
}
}
}
string file = ...
string search= ...
var result = File.ReadLines(file)
.Where(line => line.Contains(search))
.Select(line => line.Substring(
line.IndexOf(search) + search.Length + 1);
Unfortunately, none of the other solutions worked for me. I was iterating through the hashes using foreach, so I would be iterating through all the items millions of times needlessly. In the end, I did this:
using (StreamReader r = new StreamReader(#"C:\Users\****\Desktop\strings.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
lines++;
if (lines >= 6)
{
string[] bits = line.Split(':');
if(string.IsNullOrWhiteSpace(line))
{
continue;
}
try
{
strlist.Add(bits[0].Substring(10), bits[1]);
}
catch (Exception)
{
continue;
}
}
}
}
foreach(var Title in Titles)
{
string searchstr = Title.Parent.Name.ToString();
string val = Title.Value;
string has = #"Gameplay/Excel/Books/" + searchstr + ":" + val;
ulong hash = FNV64.GetHash(has);
var hash2 = " " + string.Format("0x{0:X}", hash);
try
{
if (strlist.ContainsKey(hash2))
{
list.Add(strlist[hash2]);
}
}
catch (ArgumentOutOfRangeException)
{
continue;
}
}
This gave me the output I expected in a short period of time.
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.