how to declare xpath as a string variable? C# - c#

How can I declare the following xpath value as a string variable in C#?
Value: //*[contains(concat( " ", #class, " " ), concat( " ", "lit-movie", " " ))]

You have to use escape characters (use backslash), so " should be replaced by \":
string xpath = "//*[contains(concat( \" \", #class, \" \" ), concat( \" \", \"lit-movie\", \" \" ))]";

Related

Remove \r\n\r\n from the results in a textbox

I have the following code:
txtcmdApp.Text = RunScript(#"if (Get-Process greenshot -ErrorAction silentlycontinue –ComputerName " + txtWSName.Text + " ) {'Open'} else {'Not Opened'}");
The results shown in the textbox is Not Opened but, when I use a breakpoint it is showing the following in code:
txtcmdapp|{Text = "Not Opened\r\n\r\n"}
I would like to remove the \r\n\r\n because I have an If Statement that changes the font color to red in a textbox if the results equals Not Opened and it is not working I believe because of the \r\n\r\n showing up.
Any ideas?
Regards,
Maybe simply remove the newlines?
txtcmdApp.Text = RunScript(#"if (Get-Process greenshot -ErrorAction silentlycontinue –ComputerName " + txtWSName.Text + " ) {'Open'} else {'Not Opened'}")
.Replace(Environment.NewLine, "");
This will replace all new lines (that is cr+lf (\r\n) on Windows) on the string to a empty string.
You could use Trim() on the text:
string result = RunScript(#"if (Get-Process greenshot -ErrorAction silentlycontinue –ComputerName " + txtWSName.Text + " ) {'Open'} else {'Not Opened'}");
txtcmdApp.Text = result.Trim();
This will remove any whitespace and newlines from the beginning and end of the string.

Regex with optional matching groups

I'm trying to parse given string which is kind a of path separated with /. I need to write regex that would match each segment in the path to corresponding regex group.
Example 1:
input:
/EAN/SomeBrand/appliances/refrigerators/RF444
output:
Group: producer, Value: SomeBrand
Group: category, Value: appliances
Group: subcategory, Value: refrigerators
Group: product, Value: RF4441
Example 2:
input:
/EAN/SomeBrand/appliances
output:
Group: producer, Value: SomeBrand
Group: category, Value: appliances
Group: subcategory, Value:
Group: product, Value:
I tried following code, it works fine when the path is full (like in the first exmaple) but fails to find the groups when the input string is impartial (like in example 2).
static void Main()
{
var pattern = #"^" + #"/EAN"
+ #"/" + #"(?<producer>.+)"
+ #"/" + #"(?<category>.+)"
+ #"/" + #"(?<subcategory>.+)"
+ #"/" + #"(?<product>.+)?"
+ #"$";
var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
var result = rgx.Match(#"/EAN/SomeBrand/appliances/refrigerators/RF444");
foreach (string groupName in rgx.GetGroupNames())
{
Console.WriteLine(
"Group: {0}, Value: {1}",
groupName,
result.Groups[groupName].Value);
}
Console.ReadLine();
}
Any suggestion is welcome. Unfortunately I cannot simply split the string since the framework I'm using expects regex object.
You can use optional groups (...)? and replace the .+ greedy dot matching patterns with negated character classes [^/]+:
^/EAN/(?<producer>[^/]+)/(?<category>[^/]+)(/(?<subcategory>[^/]+))?(/(?<product>[^/]+))?$
^ ^^^ ^^
See the regex demo
This is how you need to declare your regex in the C# code:
var pattern = #"^" + #"/EAN"
+ #"/(?<producer>[^/]+)"
+ #"/(?<category>[^/]+)"
+ #"(/(?<subcategory>[^/]+))?"
+ #"(/(?<product>[^/]+))?"
+ #"$";
var rgx = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
Note I am using regular capturing groups as optional ones, but the RegexOptions.ExplicitCapture flag turns all non-named capturing groups into non-capturing and thus, they do not appear among the Match.Groups. So, we only have 5 groups all the time even without using non-capturing optional groups (?:...)?.
Try
var pattern = #"^" + #"/EAN"
+ #"(?:/" + #"(?<producer>[^/]+))?"
+ #"(?:/" + #"(?<category>[^/]+))?"
+ #"(?:/" + #"(?<subcategory>[^/]+))?"
+ #"(?:/" + #"(?<product>[^/]+))?";
Note how I replaced the . with [^/], because you want to use the / to split strings. Note even the use of the optional quantifier for each sub-part (?)

C# StringBuilder with Quotes (forJSON)

I have build a JSON string (to be posted to a web service), and I used the C# StringBuilder class to do this. The problem is, that when I insert quotes, the StringBuilder class escapes them.
I am currently building the JSON string as such:
StringBuilder dataJSON= new StringBuilder();
dataJSON.Append("{");
dataJSON.Append(" " + Convert.ToChar(34) + "data" + Convert.ToChar(34) + ": {");
dataJSON.Append(" " + Convert.ToChar(34) + "urls" + Convert.ToChar(34) + ": [");
dataJSON.Append(" {" + Convert.ToChar(34) + "url" + Convert.ToChar(34) + ": " + Convert.ToChar(34) + domain + "/" + path[0] + Convert.ToChar(34) + "}");
dataJSON.Append(" ,{" + Convert.ToChar(34) + "url" + Convert.ToChar(34) + ": " + Convert.ToChar(34) + domain + "/" + path[1] + Convert.ToChar(34) + "}");
dataJSON.Append(" ]");
dataJSON.Append(" }");
dataJSON.Append("}");
However, the command:
dataJSON.ToString(); results in the string:
{ \"data\": { \"urls\": [ {\"url\": \"domain/test1.html\"} , {\"url\": \"domain/test2.html\"} ] }}
Notice the escaped quotes? This is really screwing me up, because the server can't handle the slashes.
My desired (which posts fine to my server when I use PHP) should be:
{ "data": { "urls": [ {"url": "domain/test1.html"} , {"url": "domain/test2.html"} ] }}
Is there ANY way to get a string in C# to include quotes that will result in the desired string?
Many thanks!
Brett
The QuickWatch/Watch window will add the extra \ in. If you view it in the Text Visualizer, you will not see them:
QuickWatch:
"{ \"data\": { \"urls\": [ {\"url\": \"domain/path1\"} ,{\"url\":
\"domain/path2\"} ] }}"
Visualizer (the actual output):
{ "data": { "urls": [ {"url": "domain/path1"} ,{"url": "domain/path2"} ] }}
The \ indicates that the quotes have been escaped and will be included in the final string as you're expecting them to be. I.e. there's nothing wrong with your output.
NB. I used "\"" instead of Convert.ToChar(34) when I tested this.
You may have more luck using the Newtonsoft.JSON library, or alternately just escaping the slashes yourself as \" in your string literals instead of using Char(34).
dataJSON.Append(" \"data\": {");

C# Regex: Get sub-capture?

I've got a regex...
internal static readonly Regex _parseSelector = new Regex(#"
(?<tag>" + _namePattern + #")?
(?:\.(?<class>" + _namePattern + #"))*
(?:\#(?<id>" + _namePattern + #"))*
(?<attr>\[\s*
(?<name>" + _namePattern + #")\s*
(?:
(?<op>[|*~$!^%<>]?=|[<>])\s*
(?<quote>['""]?)
(?<value>.*?)
(?<!\\)\k<quote>\s*
)?
\])*
(?::(?<pseudo>" + _namePattern + #"))*
", RegexOptions.IgnorePatternWhitespace);
For which I grab the match object...
var m = _parseSelector.Match("tag.class1.class2#id[attr1=val1][attr2=\"val2\"][attr3]:pseudo");
Now is there a way to do something akin to m.Group["attr"]["name"]? Or somehow get the groups inside the attr group?
Group names aren't nested in regular expressions - it's a flat structure. You can just use this:
m.Group["name"]

Can I write this regex in one step?

This is the input string "23x +y-34 x + y+21x - 3y2-3x-y+2". I want to surround every '+' and '-' character with whitespaces but only if they are not allready sourrounded from left or right side. So my input string would look like this "23x + y - 34 x + y + 21x - 3y2 - 3x - y + 2". I wrote this code that does the job:
Regex reg1 = new Regex(#"\+(?! )|\-(?! )");
input = reg1.Replace(input, delegate(Match m) { return m.Value + " "; });
Regex reg2 = new Regex(#"(?<! )\+|(?<! )\-");
input = reg2.Replace(input, delegate(Match m) { return " " + m.Value; });
explanation:
reg1 // Match '+' followed by any character not ' ' (whitespace) or same thing for '-'
reg2 // Same thing only that I match '+' or '-' not preceding by ' '(whitespace)
delegate 1 and 2 just insert " " before and after m.Value ( match value )
Question is, is there a way to create just one regex and just one delegate? i.e. do this job in one step? I am a new to regex and I want to learn efficient way.
I don't see the need of lookarounds or delegates here. Just replace
\s*([-+])\s*
with
" $1 "
(See http://ideone.com/r3Oog.)
I'd try
Regex.Replace(input, #"\s*[+-]\s*", m => " " + m.ToString().Trim() + " ");

Categories

Resources