Ignore case in string split C# - c#

I have a string builder and I want to ignore the case(lower or uppercase) of textbox2.Text when spliting.
Here's the line of code which I think the adjustment must be made.
String[] subStrings = e.Item.Text.Split(new String[] { textBox2.Text }, StringSplitOptions.None);
StringSplitOptions has only two option which is None and RemoveEmptyEntries
My full program would be if I type: "steph" , the text "Steph" in "Stephen" will be highlighted even the textbox2.text first character is lowercase.
My full code:
String[] subStrings = element.Text.Split(new String[] { textBox2.Text }, StringSplitOptions.);
if (subStrings.Count() >= 2)
{
StringBuilder sb = new StringBuilder();
sb.Append(subStrings[0]);
sb.Append("<color=#0193C6>" + textBox2.Text + "</color>");
sb.Append(subStrings[1]);
for (int i = 2; i < subStrings.Count(); i++)
sb.Append(textBox2.Text + subStrings[i]);
element.Text = sb.ToString();
}

Try Using Regex.Split. For e.g.
Regex.Split(textBox2.Text, "pattern", RegexOptions.IgnoreCase);

Try converting both the element and the textbox.Text ToLower().
string elementString = element.Text;
String[] subStrings = elementString.ToLower().Split(new[] { textBox2.Text.ToLower() }, StringSplitOptions.None);
if (subStrings.Count() >= 2)
{
StringBuilder sb = new StringBuilder();
sb.Append(subStrings[0]);
sb.Append("<color=#0193C6>" + textBox2.Text + "</color>");
sb.Append(subStrings[1]);
for (int i = 2; i < subStrings.Count(); i++)
sb.Append(textBox2.Text + subStrings[i]);
element.Text = sb.ToString();
}

Related

How to find all occurrences of a word in a string and move them to the beginning of the string?

Good evening formites
The task is: "Text file L4_16T.txt contains text. Delimiters are known. Move each longest word beginning with an uppercase letter to the beginning of the line with delimiters behind. Write the modified text to a separate Results.txt file. Prepare an Analysis file. txt in table format (2 columns): line number, word starting with a capital (upper) letter."
It is not possible to properly implement word wrapping in a line if there are two or more identical longest words in the line that begin with an uppercase letter.
That's because I'm looking for the maximum words in a string using IndexOf, which returns the first occurrence of the element. And since I have the same word several times in the line, the program each time transfers the same word to the beginning. And I need to transfer all the words.
I'll give you an example. There is this line:
" ,,,,,,,,,,,,,,,,,,,,,,,,Sdfsdf;;;;;;;;;;;;;;;sdfh Sdfsdf,,,,,,, ,,,,,,,,,,,,. Sdfsdf aaaaaaaaaaaaaaaaaaaaaaaaa
I should get the following output:
"Mdfsdf,,,,,,,,,Sdfsdf Sdfsdf,,,,,,,,,,,,,,,,,,,,.Sdfsdf;;;;;;;;;;;;;;; ,,,,,,,,,,,,,,,,,,,,,,,,sdfh aaaaaaaaaaaaaaaaaaaaaaaaa"
But for now I only get this line:
"Mdfsdf,,,,,,,,Sdfsdf;;;;;;;;;;;;;;;sdfh kj ,,,,,,,,,,,,,,,Sdfsdf ,,,,, ,,,,,,,,,,,,,,,.sdfsdf aaaaaaaaaaaaaaaaaaaaaaaaa
Tell me how can I solve this?
Program code:
using System;
using System.IO;
using System.Text;
namespace LAB_4_2
{
internal class Program
{
const string strFile = "TextFile.txt";
const string resFile = "Result.txt";
const string aFile = "Analiz.txt";
static void Main(string[] args)
{
char[] delimiters = { ' ', '.', ',', ';', ':', '[', ']', '(', ')', '!', '?', '\t', '\n' };
Process(strFile, aFile, resFile, delimiters);
}
static void Process(string strFile, string aFile, string resFile, char[] delimiters)
{
using (StreamReader readStr = new StreamReader(strFile, Encoding.GetEncoding(1257)))
{
using (StreamWriter writeA = new StreamWriter(aFile))
{
using (StreamWriter writeRes = new StreamWriter(resFile))
{
string top = "----------------------------\n" +
"| Line № | Longest word |\n" +
"----------------------------";
writeA.WriteLine(top);
string line;
int countline = 1;
while ((line = readStr.ReadLine()) != null) {
if (line.Length >= 0) {
string AllMaxWords = "";
string[] longestWords = FindMaxWords(line, delimiters, ref AllMaxWords);
if (AllMaxWords.Length == 0)
writeA.WriteLine("| {0, -4} | {1, -15} |", countline, "No words found");
else
for (int i = 0; i < longestWords.Length; i++)
{
if (longestWords[i] == "")
continue;
writeA.WriteLine("| {0, -4} | {1, -15} |", countline, longestWords[i]);
MoveToStart(ref line, longestWords[i], line.IndexOf(longestWords[i]));
}
countline++;
writeRes.WriteLine(line);
}
}
writeA.WriteLine("----------------------------");
}
}
}
}
static void MoveToStart(ref string myLine, string word, int start)
{
string tempLine = string.Empty;
int index = myLine.IndexOf(word) + word.Length;
while (index < myLine.Length)
{
if (myLine[index] == ' ')
{
tempLine += " ";
break;
}
else
{
tempLine += myLine[index];
index++;
}
}
string myLine1 = myLine.Remove(start, word.Length);
myLine1 = myLine1.Remove(myLine1.IndexOf(tempLine), tempLine.Length);
myLine = myLine1.Insert(0, word+tempLine);
}
static int MaxWordLength(string line, char[] delimiters)
{
int maxlength = 1;
string[] words = line.Split(delimiters,
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < words.Length; i++)
{
if (Char.IsUpper(words[i][0]) &&
maxlength < words[i].Length)
{
maxlength = words[i].Length;
}
}
return maxlength;
}
static string[] FindMaxWords(string line, char[] delimiters, ref string AllMaxWords)
{
string[] temp = line.Split(delimiters,
StringSplitOptions.RemoveEmptyEntries);
int maxlength = MaxWordLength(line, delimiters);
for (int i = 0, k = 0; i < temp.Length; i++, k++)
{
if (Char.IsUpper(temp[i][0]) &&
maxlength == temp[i].Length)
{
AllMaxWords += temp[k] + " ";
}
}
return AllMaxWords.Split();
}
}
}

Regex to match only \" not \\\"

I have to be able to split readed line of code by File.ReadLines() by ';' when i got something like that in source code (two or more code lines in one line):
string firstString = "xyzxyz"; string secodnString = "zyxzyx";
the problem is that inside those strings can be another ; or even ", and then this line:
string firstString = "xyz;xyz\"inside quote\""; string secondString =
"zyx;zyx";
readed looks like this:
"string firstString = \"xyz;xyz\\\"inside quote\\\"\"; string secondString
= \"zyx;zyx\";
So I figured that I can determine if ';' is inside string due to difference in \" and \\" by Regex, but i cant figure aout how to match \" but not to match \\" i've tried:
"[^\\\\]\"" or "[^\\]\""
but it does not work. Thanks in andvace.
EDIT, my only problem is the regex, rest of it i got already writen like that:
List<string> vrlSplitedLine = vrlLines[i].Trim().Split(';').ToList();
List<string> vrlFinallSplitedLine = new List<string>();
string vrlReatachedString = string.Empty;
for(int j = 0; j < vrlSplitedLine.Count; j++)
{
if(Regex.Matches(vrlSplitedLine[j], "[^\\\\]\"").Count % 2 != 0)
{
vrlReatachedString = vrlSplitedLine[j];
int k = j;
do
{
k++;
vrlReatachedString = vrlReatachedString + ';' + vrlSplitedLine[k];
}
while (Regex.Matches(vrlSplitedLine[k], "[^\\\\]\"").Count % 2 == 0);
vrlFinallSplitedLine.Add(vrlReatachedString);
j = k;
}
else
{
vrlFinallSplitedLine.Add(vrlSplitedLine[j]);
}
}

String split// manipulation

string keywords = "heard";
string strText = "Have you not heard!! what I said?"
string[] words = strText.Split(' ');
string result = "";
for (int i = 0; i < words.Length; i++)
{
if (words[i].Contains(keywords))
result += "<span>" + words[i] + "</span>" + " ";
else
result += words[i] + " ";
}
I get following output:
Have you not <span>heard!!</span> what I said?
Desired output:
Have you not <span>heard</span>!! what I said?
Can someone guide how can I get the desired output. The strText can only be split with a space.
Use String.Replace
var result = strText.Replace(keywords, "<span>" + keywords + "</span>");
If you have many keywords to replace, then just do replacement in a loop:
string[] keywords = { "heard", "said" };
string result = "Have you not heard!! what I said?";
foreach(var keyword in keywords)
result = result.Replace(keyword, "<span>" + keyword + "</span>");
Alternative solution is regular expression replacement:
string keywords = "heard|said";
string result = "Have you not heard!! what I said?";
result = Regex.Replace(result, keywords, m => "<span>" + m.Value + "</span>");
Why are you even looping through all words? This will give you the same:
string strText = "Have you not heard!! what I said?";
string newText = strText.Replace("heard", "<span>heard</span>");

From DataGridView to multiline commaSeparated string

I have a DataGridView with four Columns and need to crate a multiline string from its content, separated by comma.
This code works, but probably - there is a more elegant way:
string multiLine = "";
string singleLine;
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
singleLine = r.Cells[0].Value.ToString() + ","
+ r.Cells[1].Value.ToString() + ","
+ r.Cells[2].Value.ToString() + ","
+ r.Cells[3].Value.ToString() + Environment.NewLine;
multiLine = multiLine + singleLine;
}
}
I don't know about elegant, but:
use StringBuilder for string manipulation, type string is immutable!
if you need to do something in between, separate first or last cycle running (e.g. comma separation)
So, basically something like this:
StringBuilder multiLine = new StringBuilder();
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
if (r.Cells.Count > 0)
{
multiLine.Append(r.Cells[0].Value.ToString()); //first separated
for (int i = 1; i < r.Cells.Count; ++i)
{
singleLine.Append(','); //between values
singleLine.Append(r.Cells[i].Value.ToString());
}
multiLine.AppendLine();
}
}
}
To illustrate speed difference between StringBuilder concatenation (just dynamic array of characters) and string (new object and copy everything each time you use operator + concatenation), have a look at mini-program:
public static void Main()
{
var sw = new Stopwatch();
sw.Start();
StringBuilder s = new StringBuilder();
//string s = "";
int i;
for (i = 0; sw.ElapsedMilliseconds < 1000; ++i)
//s += i.ToString();
s.Append(i.ToString());
sw.Stop();
Console.WriteLine("using version with type " + s.GetType().Name + " I did " +
i + " times of string concatenation.");
}
For my computer it is:
using version with type String I did 17682 times of string concatenation.
using version with type StringBuilder I did 366367 times of string concatenation.
Try this :
string multiLine = "";
string singleLine;
foreach (DataGridViewRow r in dgvSm.Rows)
{
if (!r.IsNewRow)
{
singleLine = r.Cells[0].Value.ToString() + ","
+ r.Cells[1].Value.ToString() + ","
+ r.Cells[2].Value.ToString() + ","
+ r.Cells[3].Value.ToString() + "\r\n";
multiLine = multiLine + singleLine;
}
}

Divide long string into 60 character long lines but don't break words

There has to be a better way to do this.
I just want to split long string into 60 character lines but do not break words. So it doesn't have to add up to 60 characters just has to be less than 60.
The code below is what I have and it works but I'm thinking there's a better way. Anybody?
Modified to use StringBuilder and fixed the problem of removing a repeating word.
Also don't want to use regex because I think that would be less efficient than what I have now.
public static List<String> FormatMe(String Message)
{
Int32 MAX_WIDTH = 60;
List<String> Line = new List<String>();
String[] Words;
Message = Message.Trim();
Words = Message.Split(" ".ToCharArray());
StringBuilder s = new StringBuilder();
foreach (String Word in Words)
{
s.Append(Word + " ");
if (s.Length > MAX_WIDTH)
{
s.Replace(Word, "", 0, s.Length - Word.Length);
Line.Add(s.ToString().Trim());
s = new StringBuilder(Word + " ");
}
}
if (s.Length > 0)
Line.Add(s.ToString().Trim());
return Line;
}
Thanks
Another (now TESTED) sample, very similiar to Keith approach:
static void Main(string[] args)
{
const Int32 MAX_WIDTH = 60;
int offset = 0;
string text = Regex.Replace(File.ReadAllText("oneline.txt"), #"\s{2,}", " ");
List<string> lines = new List<string>();
while (offset < text.Length)
{
int index = text.LastIndexOf(" ",
Math.Min(text.Length, offset + MAX_WIDTH));
string line = text.Substring(offset,
(index - offset <= 0 ? text.Length : index) - offset );
offset += line.Length + 1;
lines.Add(line);
}
}
I ran that on this file with all line breaks manually replaced by " ".
Try this:
const Int32 MAX_WIDTH = 60;
string text = "...";
List<string> lines = new List<string>();
StringBuilder line = new StringBuilder();
foreach(Match word in Regex.Matches(text, #"\S+", RegexOptions.ECMAScript))
{
if (word.Value.Length + line.Length + 1 > MAX_WIDTH)
{
lines.Add(line.ToString());
line.Length = 0;
}
line.Append(String.Format("{0} ", word.Value));
}
if (line.Length > 0)
line.Append(word.Value);
Please, also check this out: How do I use a regular expression to add linefeeds?
Inside a Regular expression, the Match Evaluator function (an anonymous method) does the grunt work and stores the newly sized lines into a StringBuilder. We don't use the return value of Regex.Replace method because we're just using its Match Evaluator function as a feature to accomplish line breaking from inside the regular expression call - just for the heck of it, because I think it's cool.
using System;
using System.Text;
using System.Text.RegularExpressions;
strInput is what you want to convert the lines of.
int MAX_LEN = 60;
StringBuilder sb = new StringBuilder();
int bmark = 0; //bookmark position
Regex.Replace(strInput, #".*?\b\w+\b.*?",
delegate(Match m) {
if (m.Index - bmark + m.Length + m.NextMatch().Length > MAX_LEN
|| m.Index == bmark && m.Length >= MAX_LEN) {
sb.Append(strInput.Substring(bmark, m.Index - bmark + m.Length).Trim() + Environment.NewLine);
bmark = m.Index + m.Length;
} return null;
}, RegexOptions.Singleline);
if (bmark != strInput.Length) // last portion
sb.Append(strInput.Substring(bmark));
string strModified = sb.ToString(); // get the real string from builder
It's also worth noting the second condition in the if expression in the Match Evaluator m.Index == bmark && m.Length >= MAX_LEN is meant as an exceptional condition in case there is a word longer than 60 chars (or longer than the set max length) - it will not be broken down here but just stored on one line by itself - I guess you might want to create a second formula for that condition in the real world to hyphenate it or something.
An other one ...
public static string SplitLongWords(string text, int maxWordLength)
{
var reg = new Regex(#"\S{" + (maxWordLength + 1) + ",}");
bool replaced;
do
{
replaced = false;
text = reg.Replace(text, (m) =>
{
replaced = true;
return m.Value.Insert(maxWordLength, " ");
});
} while (replaced);
return text;
}
I would start with saving the length of the original string. Then, start backwards, and just subtract, since odds are that I would get below 60 faster by starting at the last word and going back than building up.
Once I know how long, then just use StringBuilder and build up the string for the new string.
List<string> lines = new List<string>();
while (message.Length > 60) {
int idx = message.LastIndexOf(' ', 60);
lines.Add(message.Substring(0, idx));
message = message.Substring(idx + 1, message.Length - (idx + 1));
}
lines.Add(message);
You might need to modify a bit to handle multiple spaces, words with >60 chars in them, ...
I tried the original solution and found that it didn't quite work. I've modified it slightly to make it work. It now works for me and solves a problem I had. Thanks.
Jim.
public static List<String> FormatMe(String message)
{
int maxLength = 10;
List<String> Line = new List<String>();
String[] words;
message = message.Trim();
words = message.Split(" ".ToCharArray());
StringBuilder sentence = new StringBuilder();
foreach (String word in words)
{
if((sentence.Length + word.Length) <= maxLength)
{
sentence.Append(word + " ");
}
else
{
Line.Add(sentence.ToString().Trim());
sentence = new StringBuilder(word + " ");
}
}
if (sentence.Length > 0)
Line.Add(sentence.ToString().Trim());
return Line;
}
private void btnSplitText_Click(object sender, EventArgs e)
{
List<String> Line = new List<string>();
string message = "The quick brown fox jumps over the lazy dog.";
Line = FormatMe(message);
}

Categories