Compare String with omitting the blank lines? - c#

I have two strings and need to compare them without checking the blank lines...
First string
CREATE OR REPLACE PROCEDURE "HELL_"
as
begin
dbms_output.put_line('Hello!');
end;
Second string
CREATE OR REPLACE PROCEDURE "USER1"."HELL_"
as
begin
dbms_output.put_line('Hello!');
end;
code that I am using:
string text1 = "";
string text2 = "";
if (text1.Equals(text2 ))
MessageBox.Show("same");
//no Exception
else
{
MessageBox.Show("not");
}

You can split the lines by using StringSplitOptions.RemoveEmptyEntries. The resulting string[] doesn't contain empty lines. Then Enumerable.SequenceEqual is useful.
string[] lines1 = text1.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
string[] lines2 = text2.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
bool equal = lines1.SequenceEqual(lines2);
If the "empty" lines can contain white-spaces:
var lines1 = text1.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(l => l.Trim().Length > 0);
var lines2 = text2.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(l => l.Trim().Length > 0);
and if you want to ignore white-spaces at all:
var lines1 = text1.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(l => l.Trim().Length > 0)
.Select(l => l.Trim());
var lines2 = text2.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(l => l.Trim().Length > 0)
.Select(l => l.Trim());
and if you also want to ignore the case:
bool equal = lines1.SequenceEqual(lines2, StringComparer.OrdinalIgnoreCase);

For your specific case this would do the trick:
if (firststring.Equals(secondstring.Text.Replace("\r\n\r\n", "\r\n")))
MessageBox.Show("same");
//no Exception
else
{
MessageBox.Show("not");
}

Along the same line as the other answers (by also "sanitizing" first) but more generally treats "blank lines" as any whitespace-only lines bounded by CR, LF, or any combination of the two.
string RemoveEmptyLines (string s) {
return Regex.Replace(s, #"(?:^|[\r\n]+)\s*?(?=(?:[\r\n]+|$))", "");
}
// Usage
RemoveEmptyLines(a) == RemoveEmptyLines(b)
The line-end characters (i.e. [\r\n]) may be expanded or refined as needed. This regular expression only process one blank line at a time (although all blank lines will be removed within the single Replace call) with a non-greedy quantifier and forward-lookahead. I find that this variation shows the intended operation more explicitly.

Related

Get specific data from a line of text

I need to extract the following data (in bold) from the text line below and put it into a data grid;
PERS tooldata t_rrt_ja03579:=[TRUE,[[-39.643,-0.001,1025.49],[0.382684,-0.000130001,-0.923889,0.000120001]],[200.9,[-88.1,-12.6,359.7],[1,0,0,0],29.347,50.927,18.261]];
This line is read from a file. I have managed to trim the line so it gets rid of the "PERS tooldata" and whitespaces and it leaves me with the tool name. I have it bound to data in a datagrid elsewhere in the code which is step 1 complete.
My question is how can I extract the values in bold individually and place them in to double data declarations? The first block of values (-39.643,-0.001,1025.49) is a X,Y,Z co-ordinate value and the second (0.382684,-0.000130001,-0.923889,0.000120001) are Q1,Q2,Q3,Q4.
Below is how i done the name
private void AutoFillToolData(object sender, RoutedEventArgs e)
{
// Gives user option to auto populate datagrid
var AutoFillToolResult = MessageBox.Show("Do you want to auto populate fields?", "Tool Data", MessageBoxButton.YesNo);
if (AutoFillToolResult == MessageBoxResult.Yes)
{
// User directs application to the specified file
System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
if (folderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Application looks for specific file and removes unwanted data
string robotBackupPath = folderBrowser.SelectedPath;
string allDataPath = robotBackupPath + #"\RAPID\TASK1\SYSMOD\ALL_DATA.sys";
string[] tLines = File.ReadAllLines(allDataPath);
List<string> toolDataLines = new List<string>();
foreach (string tLine in tLines)
{
if (tLine.Contains("PERS tooldata") && !tLine.StartsWith("!"))
{
if (tLine.Contains("tToolChanger")) continue;
if (tLine.Contains("tPointer")) continue;
if (tLine.Contains("tHome")) continue;
toolDataLines.Add(tLine);
}
}
foreach (string line in toolDataLines)
{
// Gets the name of the tool
ToolData toolData = GetToolNameFromLine(line);
// Puts the tool name in the DataGrid
TCPData.Add(toolData);
}
}
}
}
private ToolData GetToolNameFromLine(string line)
{
// Removes white space at the beggining of line in txt file
ToolData tooldata = new ToolData();
string[] spaceSplit = line.Trim().Split(' ');
string values = spaceSplit[2];
// Gets Tool Name
int colonLocation = values.IndexOf(":");
tooldata.ToolName = values.Substring(0, colonLocation);
return tooldata;
}
If all the samples you'll have follow the same pattern, extracting those values does not seem difficult:
//First we get all the string after the :=
string tooldata = line.Substring(data.IndexOf(":=") + 2) ;
//Split the string by [
string[] tooldataArray = tooldata.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries);
//the second and the third strings are what we are interested in
string xyzValue = tooldataArray[1].Replace(']' ,' ');
string Q1234value = tooldataArray[2].Replace(']', ' ');
If after this you want to get the individual parameters, just splitting by , would do.
Edit
This would extract all the values you want to arrays of double:
string tooldata = data.Substring(data.IndexOf(":=") + 2) ;
string[] tooldataArray = tooldata.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries);
double[] xyzValue = tooldataArray[1].Replace(']' ,' ')
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => double.Parse(s, CultureInfo.InvariantCulture))
.ToArray();
double[] Q1234value = tooldataArray[2].Replace(']', ' ')
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => double.Parse(s, CultureInfo.InvariantCulture))
.ToArray();

How to find largest word that starts with a capital and add a separator and space

I have code that finds largest word that starts with a capital letter. But I need that word to add a separator and space. Any ideas how I should do it properly?
char[] skyrikliai = { ' ', '.', ',', '!', '?', ':', ';', '(', ')', '\t' };
string eilute = "Arvydas (g. 1964 m. gruodzio 19 d. Kaune)– Lietuvos, krepsininkas, olimpinis ir pasaulio cempionas, nuo 2011 m. spalio 24 d.";
static string Ilgiausias(string eilute, char[] skyrikliai)
{
string[] parts = eilute.Split(skyrikliai,
StringSplitOptions.RemoveEmptyEntries);
string ilgiaus = "";
foreach (string zodis in parts)
if ((zodis.Length > ilgiaus.Length) && (zodis[0].ToString() == zodis[0].ToString().ToUpper()))
ilgiaus = zodis;
return ilgiaus;
}
It should find word Lietuvos and add , and space
Result should be "Lietuvos, "
I would use LINQ for that:
var ilgiaus = parts.Where(s => s[0].IsUpper())
.OrderByDescending(s => s.Length)
.FirstOrDefault();
if(ilgiaus != null) {
return ilgiaus + ", ";
}
Also you can use regex and linq. You dont need to split by many characters.
Regex regex = new Regex(#"[A-Z]\w*");
string str = "Arvydas (g. 1964 m. gruodzio 19 d. Kaune)– Lietuvos, krepsininkas, olimpinis ir pasaulio cempionas, nuo 2011 m. spalio 24 d.";
string longest = regex.Matches(str).Cast<Match>().Select(match => match.Value).MaxBy(val => val.Length);
if you dont want to use MoreLinq, instead of MaxBy(val => val.Length) you can do OrderByDescending(x => x.Length).First()
There are probably more ingenious and elegant ways, but the following pseudocode should work:
List<String> listOfStrings = new List<String>();
// add some strings to the generic list
listOfStrings.Add("bla");
listOfStrings.Add("foo");
listOfStrings.Add("bar");
listOfStrings.Add("Rompecabeza");
listOfStrings.Add("Rumpelstiltskin");
. . .
String longestWorld = String.Empty;
. . .
longestWord = GetLongestCapitalizedWord(listOfStrings);
. . .
private String GetLongestCapitalizedWord(List<String> listOfStrings)
{
foreach (string s in listofstrings)
{
if ((IsCapitalized(s) && (s.Len > longestWord.Len)))
{
longestWord = s;
}
}
}
private bool IsCapitalized(String s)
{
return // true or false
}

How to modify linq index number

How do I modify the index number from an array to have a preceding 0 for number 1 - 9.
However, I would like numbers 10 on up to remain the same.
This is the raw data from debugging when getting my data from the tb1.text
"1ABC\r\n2ABC\r\3ABC\r\4ABC\r\n5ABC"
This is how I would like to store the data in my localDB.
"01ABC\r\n02ABC\r\03ABC\r\04ABC\r\n...10ABC"
Here is what I have so far.
var lines = tb1.Text.Split('\n').Select((line, index) => "YRZ"+(index + 01) + line).ToArray();
var res = string.Join("\n", lines);
Since the indexes are already part of the data entered, you need to either read it from there (and use that index) or remove it from there (and use the index you can get while Selecting). You can parse it using a regular expression. Once you have the index isolated, you can use .ToString("00") to add a leading zero.
var regex = new Regex(#"^(\d+)(.*)$");
var result = string.Join("\r\n",
tb1.Text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x =>
{
var m = regex.Match(x);
return int.Parse(m.Groups[1].Value).ToString("00") + m.Groups[2].Value;
}));
Debug.Assert("01ABC\r\n02ABC\r\n03ABC\r\n04ABC\r\n10ABC" == result);
If you only want 0 in the string why not updating it as a string:
var text = "1ABC\r\n2ABC\r\n3ABC\r\n4ABC\r\n5ABC";
var lines = text.Split('\n').ToList();
var withZero = lines.Select(
(line, i) =>
{
var newVal = i < 9 ? string.Format("0{0}", line) : line;
return newVal;
});
var result = string.Join("\n", withZero);
Or in a more concise form:
var result = string.Join("\n", text.Split('\n').Select(
(line, i) =>
{
var newVal = i < 9 ? string.Format("0{0}", line) : line;
return newVal;
}));

How can I change code inside a <pre></pre> and change it into a table without losing empty lines?

I have been using some code that takes as input HTML and then changes
code inside a <pre> ... </pre> and makes it into a table. Here's the
code:
public static string FormatCode(this string content)
{
var data1 = content
.Split(new[] { "<pre>", "</pre>" }, StringSplitOptions.None);
var data2 = data1
.Select((s, index) =>
{
string s1 = index % 2 == 1 ? string.Format("{0}{2}{1}",
"<table class='code'>", "</table>", SplitJoin(s)) : s;
return s1;
});
var data3 = data2.Where(s => !string.IsNullOrEmpty(s));
var data4 = string.Join("\n", data3);
return data4;
}
private static string SplitJoin(string content)
{
IEnumerable<String> code =
content.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select((line, index) =>
string.Format("<tr><td>{0}</td><td><pre><code>{1}</code></pre></td></tr>\n",
(index + 1).ToString("D2"), HttpUtility.HtmlEncode(line)));
return string.Join("", code) + "\n";
}
If my HTML is like this:
<p>xxx</p><pre>public enum XXX {
private String command1;
private String command2;
}
}</pre>
It converts this into:
<table class="code"><tbody>
<tr><td>01</td><td><p>xxx</p></td></tr>
<tr><td>02</td><td><pre>public enum XXX {</pre></td></tr>
<tr><td>03</td><td><pre> private String command1;</pre></td></tr>
<tr><td>04</td><td><pre> private String command2;</pre></td></tr>
<tr><td>05</td><td><pre>}</pre></td></tr>
</tbody></table>
The problem is that empty line inside a <pre> are not output. Can someone help me
by telling me how I could change my code so that when there is an empty line in the
<pre> then it still outputs a row with a correct row number and something with an
Update: Following a suggested answer I tried making a change to my function to this:
IEnumerable<String> code =
// content.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
content.Split(new[] { '\n' }, StringSplitOptions.None)
.Select((line, index) =>
string.Format("<tr><td>{0}</td><td><pre><code>{1}</code></pre></td></tr>\n",
(index + 1).ToString("D2"), HttpUtility.HtmlEncode(line)));
return string.Join("", code) + "\n";
However I still do not see the empty lines in the tables.
StringSplitOptions.RemoveEmptyEntries removes empty entries when splitting on the newline character. If you don't want to remove empty entries, don't use this option.

Split string to array, remove empty spaces

I have a question about splitting string. I want to split string, but when in string see chars "" then don't split and remove empty spaces.
My String:
String tmp = "abc 123 \"Edk k3\" String;";
Result:
1: abc
2: 123
3: Edkk3 // don't split after "" and remove empty spaces
4: String
My code for result, but I don't know how to remove empty spaces in ""
var tmpList = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
{
if (i % 2 == 1) return new[] { s };
return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
}).ToList();
Or but this doesn't see "", so it splits everything
string[] tmpList = tmp.Split(new Char[] { ' ', ';', '\"', ',' }, StringSplitOptions.RemoveEmptyEntries);
Add .Replace(" ","")
String tmp = #"abc 123 ""Edk k3"" String;";
var tmpList = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
{
if (i % 2 == 1) return new[] { s.Replace(" ", "") };
return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
}).ToList();
string.Split is not suitable for what you want to do, as you can't tell it to ignore what is in the ".
I wouldn't go with Regex either, as this can get complicated and memory intensive (for long strings).
Implement your own parser - using a state machine to track whether you are within a quoted portion.
You can use a regular expression. Instead of splitting, specify what you want to keep.
Example:
string tmp = "abc 123 \"Edk k3\" String;";
MatchCollection m = Regex.Matches(tmp, #"""(.*?)""|([^ ]+)");
foreach (Match s in m) {
Console.WriteLine(s.Groups[1].Value.Replace(" ", "") + s.Groups[2].Value);
}
Output:
abc
123
Edkk3
String;

Categories

Resources