C# String.Trim() not removing characters from MailMessage.Subject - c#

I'm trying to eliminate certain symbols from the Subject property of a MailMessage object. What I'm experiencing is that it does nothing. Even after assigning Subject to a string, and trimming that, the final Subject still has the symbols in it. (not showed in example)
MailMessage mailMessage = new MailMessage
{
From = new MailAddress(mail.SenderEmailAddress),
SubjectEncoding = System.Text.Encoding.UTF8,
Subject = mail.Subject.Trim(new char[] {}), //symbol list, like ":", "~", ">"
Body = mail.Body
};
String path = #"C:\Users\" + Environment.UserName + #"\Documents\EML\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path = #"C:\Users\" + Environment.UserName + #"\Documents\EML\"
+ mailMessage.Subject + ".eml";
MessageBox.Show(path);
The message box is just to see whether the symbol gets removed or not at the moment, path will be put into a method later.
mail has subject RE: dog, .Trim tries to remove :,
MessageBox shows C:\Users\user\Documents\EML\RE: dog.eml.

The String.Trim(Char[]) method, as per official MSDN documentation, removes all leading and trailing occurrences of a set of characters specified in an array from the current string object. If you want to remove all the occurrences of a specified list of characters from the string, even when they don't appear at the beginning or at the end of it, you may want to use a different approach.
Given the following example string and the following replacements:
String text = "This is: the~ mail sub~ject!";
Char[] replacements = new Char[] { ':', '~' };
you can perform this operation using various approaches. Here is a list containing a few of them:
1) Using String.Split and String.Join
text = String.Join(String.Empty, text.Split(replacements));
2) Using LINQ
text = new String
(
(from c in text
where !replacements.Contains(c)
select c).ToArray()
);
or:
text = new String(text.Where(c => !replacements.Contains(c)).ToArray());
3) Using Regular Expressions
text = Regex.Replace(text, "[:~]", String.Empty);
4) Using a Loop and String.Replace
foreach (Char c in replacements)
text = text.Replace(c.ToString(), String.Empty);
5) Using an Extension Method
public static String RemoveChars(this String input, params Char[] chars)
{
StringBuilder builder = new StringBuilder();
for (Int32 i = 0; i < input.Length; ++i)
{
if (!chars.Contains(input[i]))
builder.Append(input[i]);
}
return builder.ToString();
}
text = text.RemoveChars(replacements);
The final output is always the same:
This is the mail subject!

From MSDN:
String.Trim Method () - Removes all leading and trailing white-space characters from the current String object.
So, Trim isn't going to remove characters from the middle of a String. Commenters suggested using Replace instead, but there isn't a signature that takes an array of characters like you are using. An easy way around that is Extension methods.
class Program
{
static void Main(string[] args)
{
string text = "This:is~a>test";
string subject = text.ReplaceFromCollection(new char[] { ':', '~', '>'}); //symbol list, like ":", "~", ">"
Console.WriteLine($"{text}\n{subject}");
Console.ReadLine();
}
}
static class Extensions
{
public static String ReplaceFromCollection(this string text, IEnumerable<char> characters)
{
foreach (var chr in characters)
{
text = text.Replace(chr.ToString(), String.Empty);
}
return text;
}
}
Using this, each character in your string that matches a character in the array is replaced with the empty String one by one. The result is then passed back.
More reading on Extension Methods.

Related

How can I Replace special characters

I've got a string value with a lot of different characters
I want to:
replace TAB,ENTER, with Space
replace Arabic ي with Persian ی
replace Arabic ك with Persian ک
remove newlines from both sides of a string
replace multiple space with one space
Trim space
The following Function is for cleaning data. and it works correctly.
Does anyone have any idea for better performance and less code for maintenance :)
static void Main(string[] args)
{
var output = "كgeeks 01$سهيلاطريقي03. اشك!#!!.ي";
//output = output.Replace("\u064A", "\u0649");//ي
output = output.Replace("\u064A", "\u06CC");//replace arabic ي with persian ی
output = output.Replace("\u0643", "\u06A9");//replace arabic ك with persian ک
output = output.Trim('\r', '\n');//remove newlines from both sides of a string
output = output.Replace("\n", "").Replace("\r", " ");//replace newline with space
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);//replace multiple space with one space
output = regex.Replace(output, " ");
char tab = '\u0009';
output = output.Replace(tab.ToString(), "");
Console.WriteLine(output);
}
You can refactor using two lists: one for the trim process and one for the replace process.
var itemsTrimChars = new List<char>()
{
'\r',
'\n'
};
var itemsReplaceStrings = new Dictionary<string, string>()
{
{ "\n", "" },
{ "\r", " " },
{ "\u064A", "\u06CC" },
{ "\u0643", "\u06A9" },
{ "\u0009", "" }
}.ToList();
Thus they are maintenable tables with the technology you want: as local in this example, declared at the level of a class, using tables in a database, using disk text files...
Used like that:
itemsTrimChars.ForEach(c => output = output.Trim(c));
itemsReplaceStrings.ForEach(p => output = output.Replace(p.Key, p.Value));
For the regex to replace double spaces, I know nothing about, but if you need to replace other doubled, you can create a third list.
You can do this by iterating over each character and apply those rules, forming a new output string that is the format you want. It should be faster than all those string.Replace, and Regex.Match.
Use string builder for performance when appending, don't use string += string
First Find Character in your string and then remove it and in the same index add new character
private string ReplaceChars(string Source, string Find, string Replace)
{
int Place = Source.IndexOf(Find);
string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
return result;
}
Usage :
text= "كgeeks 01$سهيلاطريقي03. اشك!#!!.ي";
var result =ReplaceChars(text,"ي","ی");

Complex string split C#

I have input file like this:
input.txt
aa#aa.com bb#bb.com "Information" "Hi there"
cc#cc.com dd#dd.com "Follow up" "Interview"
I have used this method:
string[] words = item.Split(' ');
However, it splits every words with space. I also have spaces in quotes strings but I won't split those spaces.
Basically I want to parse this input from file to this output:
From = aa#aa.com
To = bb#bb.com
Subject = Information
Body = Hi there
How do I split these strings in C#?
Simply you can use Regex as it is said in this question
var stringValue = "aa#aa.com bb#bb.com \"Information\" \"Hi there\"";
var parts = Regex.Matches(stringValue, #"[\""].+?[\""]|[^ ]+")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
//parts: aa#aa.com
bb#bb.com
"Information"
"Hi there"
Also you may try Replace function to remove those " characters.
The String.Split() method has an overload that allows you to specify the number of splits required. You can get what you want like this:
Read one line at a time
Call input.Split(new string[" "], 3, StringSplitOptions.None) - this returns an array of strings with 3 parts. Since email addresses don't have spaces in them, the first two strings will be the from/to addresses, and the third string will be the subject and message. Assume the result of this call is stored in firstSplit[], then firstSplit[0] is the from address, firstSplit[1] is the to address, and firstSplit[2] is the subject and message combined.
Call firstSplit[2].Split(new string[""" """], 2, StringSplitOptions.None) - this searches for the string " " in the concatenated subject+message from the previous call, which should pinpoint the separator between the end of the subject and the start of the message. This will give you the subject and message in another array. (The double-quotes inside are doubled to escape them)
This assumes you disallow double quotes in your subject and message. If you do allow double quotes, then you need to ensure you escape them before putting it in the file in the first place.
You can do this without using regex by just using IndexOf and SubString just put it in a loop if you have multiple emails to parse.
It's not pretty but it would be faster than RegEx if you're doing a lot of them.
string content = #"abba#aa.com dddb#bdd.com ""Information"" ""Hi there""";
string firstEmail = content.Substring(0, content.IndexOf(" ", StringComparison.Ordinal));
string secondEmail = content.Substring(firstEmail.Length, content.IndexOf(" ", firstEmail.Length + 1) - firstEmail.Length);
int firstQuote = content.IndexOf("\"", StringComparison.Ordinal);
string subjectandMessage = content.Substring(firstQuote, content.Length - content.IndexOf("\"", firstQuote, StringComparison.Ordinal));
String[] words = subjectandMessage.Split(new string[] { "\" \"" }, StringSplitOptions.None);
Console.WriteLine(firstEmail);
Console.WriteLine(secondEmail);
Console.WriteLine(words[0].Remove(0,1));
Console.WriteLine(words[1].Remove(words[1].Length -1));
Output:
aa#aa.com
bb#bb.com
Information
Hi there
As Spencer pointed out, read this file line by line using File.ReadAllLines() method and then apply String.Split[] method with spaces using something like this:
string[] elements = string.Split(new char[0]);
UPDATE
Not a pretty solution, but this is how I think it can work:
string[] readText = File.ReadAllLines(' ');
//Take value of first 3 fields by simple readText[index]; (index: 0-2)
string temp = "";
for(int i=3; i<readText.Length; i++)
{
temp += readText[i];
}
Requires reference to Microsoft.VisualBasic, but a bit more reliable than Regex:
using (var tfp = new Microsoft.VisualBasic.FileIO.TextFieldParser("input.txt")) {
for (tfp.SetDelimiters(" "); !tfp.EndOfData;) {
string[] fields = tfp.ReadFields();
Debug.Print(string.Join(",", fields)); // "aa#aa.com,bb#bb.com,Information,Hi there"
}
}

c# replace each instance of a character selection in a string

I've found many references to do similar to this but none seem to be exactly what I'm after, so hoping someone could help.
In simple terms, I want to take a string entered by a user (into a Winform input), and firstly strip out any blanks, then replace any of a list of 'illegal' characters with the UK currency symbol (£). The requirement is for the input to be used but the file that is generated by the process has the modified filename.
I wrote a function (based on an extension method) but it's not working quite as expected:
public static class ExtensionMethods
{
public static string Replace(this string s, char[] separators, string newVal)
{
var temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
return String.Join(newVal, temp);
}
}
public static string RemoveUnwantedChars(string enteredName, char[] unwanted, string rChar)
{
return enteredName.Replace(unwanted, rChar);
}
Which in my code, I've called twice:
char[] blank = { ' ' };
string ename = Utilities.RemoveUnwantedChars(this.txtTableName.Text, blank, string.Empty);
char[] unwanted = { '(', ')', '.', '%', '/', '&', '+' };
string fname = Utilities.RemoveUnwantedChars(ename, unwanted, "£");
If I enter a string that contains at least one space, all of the characters above and some other letters (for example, " (GH) F16.5% M X/Y&1+1"), I get the following results:
ename = "(GH)F16.5%MX/Y&1+1" - this is correct in that it has removed the blanks.
fname = "GH£F16£5£MX£Y£1£1" - this hasn't worked correctly in that it has not replaced the first character but removed it.
The rest of the characters have been correctly replaced. It only occurs when one of the 'illegal' characters is at the start of the string - if my string was "G(H) F16.5% M X/Y&1+1", I would correctly get "G£H£F16£5£MX£Y£1£1". It also replaces multiple 'illegal' characters with one '£', so "M()GX+.1" would become "M£GX£1" but should be "M££GX££1".
I think the problem is in your Replace extension. You are splitting in this line
var temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
You are removing empty entries causing the unexpected result. Use this instead:
var temp = s.Split(separators, StringSplitOptions.None);
The problem is occuring because string.Join() only puts separators between substrings - it will never put one at the start.
One possible solution is to avoid using string.Join() and write Replace() like this instead:
public static class ExtensionMethods
{
public static string Replace(this string s, char[] separators, string newVal)
{
var sb = new StringBuilder(s);
foreach (char ch in separators)
{
string target = new string(ch, 1);
sb.Replace(target, newVal);
}
return sb.ToString();
}
}
When you use split method in your Replace function you get following strings:
GH, F16, 5, MX, Y, 1, 1.
When you join them with your newVal you get:
GH + newVal + F16 + newVal + ... thus omitting first replaced character.
You would probably need some special case to check if first char is "illegal" and put newVal at start of your string.

Find link in a string by regex

So i have a String like so
String org = "Go to http://Apple.com, to see the new Ipad";
How do i return a list of all the words in the String including the url?
For example. The above string should return this list
List<String> chopped = new List<String>(){"Go", "to", "http://Apple.com", " to", "see" , " the", " new", " Ipad"};
I am doing this because i want to reconstruct the string but use the link for something else.
Use string.Split method:
string[] chopped = org.Split(' ');
It returns array of string instead of List<string>.
But you'll still have to take care of characters like ,. You can try doing following:
string []chopped = org.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
It will split using both a space and a comma and return results ignoring empty ones.

String.Replace(char, char) method in C#

How do I replace \n with empty space?
I get an empty literal error if I do this:
string temp = mystring.Replace('\n', '');
String.Replace('\n', '') doesn't work because '' is not a valid character literal.
If you use the String.Replace(string, string) override, it should work.
string temp = mystring.Replace("\n", "");
As replacing "\n" with "" doesn't give you the result that you want, that means that what you should replace is actually not "\n", but some other character combination.
One possibility is that what you should replace is the "\r\n" character combination, which is the newline code in a Windows system. If you replace only the "\n" (line feed) character it will leave the "\r" (carriage return) character, which still may be interpreted as a line break, depending on how you display the string.
If the source of the string is system specific you should use that specific string, otherwise you should use Environment.NewLine to get the newline character combination for the current system.
string temp = mystring.Replace("\r\n", string.Empty);
or:
string temp = mystring.Replace(Environment.NewLine, string.Empty);
This should work.
string temp = mystring.Replace("\n", "");
Are you sure there are actual \n new lines in your original string?
string temp = mystring.Replace("\n", string.Empty).Replace("\r", string.Empty);
Obviously, this removes both '\n' and '\r' and is as simple as I know how to do it.
If you use
string temp = mystring.Replace("\r\n", "").Replace("\n", "");
then you won't have to worry about where your string is coming from.
One caveat: in .NET the linefeed is "\r\n". So if you're loading your text from a file, you might have to use that instead of just "\n"
edit> as samuel pointed out in the comments, "\r\n" is not .NET specific, but is windows specific.
What about creating an Extension Method like this....
public static string ReplaceTHAT(this string s)
{
return s.Replace("\n\r", "");
}
And then when you want to replace that wherever you want you can do this.
s.ReplaceTHAT();
Best Regards!
Here is your exact answer...
const char LineFeed = '\n'; // #10
string temp = new System.Text.RegularExpressions.Regex(
LineFeed
).Replace(mystring, string.Empty);
But this one is much better... Specially if you are trying to split the lines (you may also use it with Split)
const char CarriageReturn = '\r'; // #13
const char LineFeed = '\n'; // #10
string temp = new System.Text.RegularExpressions.Regex(
string.Format("{0}?{1}", CarriageReturn, LineFeed)
).Replace(mystring, string.Empty);
string temp = mystring.Replace("\n", " ");
#gnomixa - What do you mean in your comment about not achieving anything? The following works for me in VS2005.
If your goal is to remove the newline characters, thereby shortening the string, look at this:
string originalStringWithNewline = "12\n345"; // length is 6
System.Diagnostics.Debug.Assert(originalStringWithNewline.Length == 6);
string newStringWithoutNewline = originalStringWithNewline.Replace("\n", ""); // new length is 5
System.Diagnostics.Debug.Assert(newStringWithoutNewline.Length == 5);
If your goal is to replace the newline characters with a space character, leaving the string length the same, look at this example:
string originalStringWithNewline = "12\n345"; // length is 6
System.Diagnostics.Debug.Assert(originalStringWithNewline.Length == 6);
string newStringWithoutNewline = originalStringWithNewline.Replace("\n", " "); // new length is still 6
System.Diagnostics.Debug.Assert(newStringWithoutNewline.Length == 6);
And you have to replace single-character strings instead of characters because '' is not a valid character to be passed to Replace(string,char)
I know this is an old post but I'd like to add my method.
public static string Replace(string text, string[] toReplace, string replaceWith)
{
foreach (string str in toReplace)
text = text.Replace(str, replaceWith);
return text;
}
Example usage:
string newText = Replace("This is an \r\n \n an example.", new string[] { "\r\n", "\n" }, "");
Found on Bytes.com:
string temp = mystring.Replace('\n', '\0');// '\0' represents an empty char

Categories