C# String compare not working - c#

I'm having some issues with the string comparison of a string the is received by Request.queryString and a line from a file .resx.
The code receive Request.queryString to a variable named q, then it goes to a function to compare if a line has q value in it:
while ((line = filehtml.ReadLine()) != null)
{
if (line.ToLower().Contains(q.ToLower().ToString()))
HttpContext.Current.Response.Write("<b>Content found!</b>");
else
HttpContext.Current.Response.Write("<b>Content not found!</b>");
}
As it's a search in static files, special characters must be consider and seraching for: Iberê for example, isn't returning true because the .Contains, .IndexOf or .LastindexOf is comparing: iberê, that is coming from q, with iberê that is coming from the line.
Consider that I already tried to use ResXResourceReader (which can't be found by Visual Studio), ResourceReader and ResourceManager (these I couldn't set a static file by the path to be read).
EDIT:
Problem solved. There was a instance of SpecialChars, overwriting q value with EntitiesEncode method

The problem is that the ê character is escaped in both strings. So if you did something like this, it wouldn't work:
string line = "sample iberê text";
string q = "iberê";
if (line.Contains(q)) {
// do something
}
You need to unscape the strings. Use HttpUtility in the System.Web assembly. This will work:
line = System.Web.HttpUtility.HtmlDecode(line);
q = System.Web.HttpUtility.HtmlDecode(q);
if (line.Contains(q)) {
// do something
}
As suggested by #r3bel below, if you're using .net 4 or above you can also use System.Net.WebUtility.HtmlDecode, so you don't need an extra assembly reference.

Related

How to change text dynamic in unity

at line 161,I want to insert my text in parameter t,but it won't change when i debug it.although the parameter tmp had alredy changed.
I want to change this Text in UI,when my parameter t changes.
With respect to your specific issue, Insert is defined as:
public string Insert (int startIndex, string value);
and returns a new string. In C#, strings aren't modified, new strings are created. In this way, they act like a value type, even though they're a reference type. In other words, once a string is created, it is never modified - it's 'immutable'. So, you need to store your newly created string.
In cases like this, I like to use the string interpolation, as it allows me to get a slightly clearer representation of what the final string will look like.
var tmp = System.Text.Encoding.UTF8.GetString ( e.Message );
t.text = $"{tmp}\n{t.text}"; // Note that a newline is represented as \n
Or, if you add the System.Text namespace; you could reduce it down to:
using System.Text;
...
t.text = $"{Encoding.UTF8.GetString ( e.Message )}\n{t.text}";
The string type in c# is immutable, therefore Insert returns a new string instead of modifying the current one.
Do:
t = t.text.Insert(0, tmp + "//n");
See also
How to modify string contents in C#

C# How to treat a string variable as interpolated string?

the interpolated string is easy, just a string lead with $ sign. But what if the string template is coming from outside of your code. For example assume you have a XML file containing following line:
<filePath from="C:\data\settle{date}.csv" to="D:\data\settle{date}.csv"/>
Then you can use LINQ to XML read the content of the attributes in.
//assume the ele is the node <filePath></filePath>
string pathFrom = ele.Attribute("from").value;
string pathTo = ele.Attibute("to").value;
string date = DateTime.Today.ToString("MMddyyyy");
Now how can I inject the date into the pathFrom variable and pathTo variable?
If I have the control of the string itself, things are easy. I can just do var xxx=$"C:\data\settle{date}.csv";But now, what I have is only the variable that I know contains the placeholder date
String interpolation is a compiler feature, so it cannot be used at runtime. This should be clear from the fact that the names of the variables in the scope will in general not be availabe at runtime.
So you will have to roll your own replacement mechanism. It depends on your exact requirements what is best here.
If you only have one (or very few replacements), just do
output = input.Replace("{date}", date);
If the possible replacements are a long list, it might be better to use
output = Regex.Replace(input, #"\{\w+?\}",
match => GetValue(match.Value));
with
string GetValue(string variable)
{
switch (variable)
{
case "{date}":
return DateTime.Today.ToString("MMddyyyy");
default:
return "";
}
}
If you can get an IDictionary<string, string> mapping variable names to values you may simplify this to
output = Regex.Replace(input, #"\{\w+?\}",
match => replacements[match.Value.Substring(1, match.Value.Length-2)]);
You can't directly; the compiler turns your:
string world = "world";
var hw = $"Hello {world}"
Into something like:
string world = "world";
var hw = string.Format("Hello {0}", world);
(It chooses concat, format or formattablestring depending on the situation)
You could engage in a similar process yourself, by replacing "{date" with "{0" and putting the date as the second argument to a string format, etc.
SOLUTION 1:
If you have the ability to change something on xml template change {date} to {0}.
<filePath from="C:\data\settle{0}.csv" to="D:\data\settle{0}.csv" />
Then you can set the value of that like this.
var elementString = string.Format(element.ToString(), DateTime.Now.ToString("MMddyyyy"));
Output: <filePath from="C:\data\settle08092020.csv" to="D:\data\settle08092020.csv" />
SOLUTION 2:
If you can't change the xml template, then this might be my personal course to go.
<filePath from="C:\data\settle{date}.csv" to="D:\data\settle{date}.csv" />
Set the placeholder like this.
element.Attribute("to").Value = element.Attribute("to").Value.Replace("{date}", DateTime.Now.ToString("MMddyyyy"));
element.Attribute("from").Value = element.Attribute("from").Value.Replace("{date}", DateTime.Now.ToString("MMddyyyy"));
Output: <filePath from="C:\data\settle08092020.csv" to="D:\data\settle08092020.csv" />
I hope it helps. Kind regards.
If you treat your original string as a user-input string (or anything that is not processed by the compiler to replace the placeholder, then the question is simple - just use String.Replace() to replace the placehoder {date}, with the value of the date as you wish. Now the followup question is: are you sure that the compiler is not substituting it during compile time, and leaving it untouched for handling at the runtime?
String interpolation allows the developer to combine variables and text to form a string.
Example
Two int variables are created: foo and bar.
int foo = 34;
int bar = 42;
string resultString = $"The foo is {foo}, and the bar is {bar}.";
Console.WriteLine(resultString);
Output:
The foo is 34, and the bar is 42.

Cannot split string from a list to two parts

I'm trying to create an configuration file for my server program. I'm reading it line by line and when encounter desired option I'm processing that line. I have to extract IP written to file, but Visual Studio won't let me.
Here is code of process method:
////I'm assuming that file is loading is good...
private int processIp()
{
String tempIpAddr = "";
Console.Write("IP");
for (int i = 0; i < readLines.Count; i++)
{
if (readLines[i].Contains("IP"))
{
if(readLines[i].Contains(":"))
{
tempIpAddr = readLines.ElementAt(i).Split(':');
}
}
}
return 0;
}
I'm getting that error:Error 4 Cannot implicitly convert type 'string[]' to 'string' F:\DB\Dropbox\Repozytoria\ARDSQL GUI\Sources\Configuration.cs 85 38 ARDSQL GUI
I tried changing tempIpAddr to array and changing this readLines.ElementAt(i).Split(':'); to this tempIpAddr = readLines[i].Split(':');
How to make it work?
The result of String.Split() is a string array string[].
Adjust your declaration to look like this:
String[] tempIpAddr;
string.Split() returns an array of strings, and you are trying to assign that to a string variable , which won't work.
If you know that the IP address is always the string segment following the very first ':' on the line, and that there will be nothing following the IP address, you could modify your code thus:
tempIpAddr = readLines.ElementAt(i).Split(':')[1]
But trusting your client is a sure-fire way to fail. And I would at least do a Trim() after the Split().
(There are a few other problems in your code, but you may already be aware of them: i.e. you aren't returning the temp IP address or doing anything else with it.)

Execute code from external file using Roslyn

I'm using Roslyn to execute C# code at runtime.
First I tried this code (which works fine) :
engine.Execute(#"System.Console.WriteLine(""Hello World"");");
After that, I wanted to execute code from a text file, so I did this :
string line;
System.IO.StreamReader file = new System.IO.StreamReader("test.txt");
while ((line = file.ReadLine()) != null)
{
engine.Execute(line);
}
I copied the string that I used before in a external file called test.txt.
So my test.txt contains the following line : #"System.Console.Write(""Hello World"");"
When compliling the code I get an error that something is missing.
So I figured out that, it was just the backslash.
And changed the code to this :
string line;
System.IO.StreamReader file = new System.IO.StreamReader("test.txt");
while ((line = file.ReadLine()) != null)
{
string toto = line;
string titi = toto.Replace(#"\\", #"");
engine.Execute(toto);
}
Now when I run this code, nothing happens (no error).
And when I inspect the variables content, I get this :
toto : "#\"System.Console.Write(\"\"Hello World\"\");\""
titi : "#\"System.Console.Write(\"\"Hello World\"\");\""
Is that normal ! Normally the baskslash should be removed, but it not the case.
What's the problem
EDIT
I want to keep the exact string that I passe to Roslyn in code, so don't suggest answers like change the string in the file. Another solutions please !
You're misunderstanding strings.
#"..." is a string literal; it creates a string with a value of ....
Therefore, when you write Execute(#"System.Console.WriteLine(""Hello World"");"), the actual value that you pass to Execute() is System.Console.WriteLine("Hello World");
When you read a string from a file, you get the actual value of the string.
StreamReader does not assume that the file contains a C# string literal expression (that would be extremely weird, unexpected, and useless).
Therefore, when you read a file containing the text #"System.Console.WriteLine(""Hello World"");", you get a string with the actual value #"System.Console.WriteLine(""Hello World"");".
(to write this in a string literal, you would need to write #"#""System.Console.WriteLine(""""Hello World"""");"""")
When you then pass that string to Roslyn's Execute() method, Roslyn evaluates the string literal expression, and returns the string value of the literal.

Regex matches in C# but not in java

I have the following regex (long, I know):
(?-mix:((?-mix:(?-mix:\{\%).*?(?-mix:\%\})|(?-mix:\{\{).*?(?-mix:\}\}?))
|(?-mix:\{\{|\{\%)))
that I'm using to split a string. It matches correctly in C#, but when I moved the code to Java, it doesn't match. Is there any particular feature of this regex that is C#-only?
The source is produced as:
String source = Pattern.quote("{% assign foo = values %}.{{ foo[0] }}.");
While in C# it's:
string source = #"{% assign foo = values %}.{{ foo[0] }}.";
The C# version is like this:
string[] split = Regex.split(source, regex);
In Java I tried both:
String[] split = source.split(regex);
and also
Pattern p = Pattern.compile(regex);
String[] split = p.split(source);
Here is a sample program with your code: http://ideone.com/hk3uy
There is a major difference here between Java and other languages: Java does not add captured groups as tokens in the result array (example). That means that all delimiters are removed from result, though they would be included in .Net.
The only alternative I know is not to use split, but getting a list of matches and splitting manually.
I think the problem is with how you're defining source. On my system, this:
String source = Pattern.quote("{% assign foo = values %}.{{ foo[0] }}.");
is equivalent to this:
String source = "\\Q{% assign foo = values %}.{{ foo[0] }}.\\E";
(that is, it adds a stray \Q and \E), but the way the method is defined, your Java implementation could treat it as equivalent to this:
String source = "\\{% assign foo = values %\\}\\.\\{\\{ foo\\[0\\] \\}\\}\\.";
(that is, inserting lots of backslashes).
Your regex itself seems fine. This program:
public static void main(final String... args)
{
final Pattern p = Pattern.compile("(?-mix:((?-mix:(?-mix:\\{\\%).*?(?-mix:\\%\\})|(?-mix:\\{\\{).*?(?-mix:\\}\\}?))|(?-mix:\\{\\{|\\{\\%)))");
for(final String s : p.split("a{%b%}c{{d}}e{%f%}g{{h}}i{{j{%k"))
System.out.println(s);
}
prints
a
c
e
g
i
j
k
that is, it successfully treats {%b%}, {{d}}, {%f%}, {{h}}, {{, and {% as split-points, with all the non-greediness you'd expect. But tor the record, it also works if I strip p down to just
Pattern.compile("\\{%.*?%\\}|\\{\\{.*?\\}\\}?|\\{\\{|\\{%");
;-)
use \\{ instead of \{ and for other symbols too

Categories