I am most familiar with PowerShell and have recently moved into using C# as my primary language. In PowerShell it's possible to do the following
$var1 = "abc"
"abc" -match "$var1"
This results in a true statement.
I would like to do be able to do the same thing in C#. I know that you can use interpolation with C# and I have tries various ways of trying to use Regex.Match() with no luck.
Example:
string toMatch = "abc";
var result = Regex.Match("abc", $"{{toMatch}}");
var a = Regex.Match("abc", $"{{{toMatch}}}");
var b = Regex.Match("abc", $"{toMatch}");
var c = Regex.Match(toMatch,toMatch);
None of the above seems to work. I am not even sure if what I am trying to do is possible in C#. Ideally I'd like to be able to use a combination of variables and Regex for a match. Something even like this Regex.Match(varToMatch,$"{{myVar}}\\d+\\w{4}")
edit:
After reading some answers here and trying some code out it appears that my real issue is trying to match up against a directory path. Something like "C:\temp\abcfile". For example:
string path = #"C:\temp\abc";
string path2 = #"C:\temp\abc";
string fn = path.Split('\\').LastOrDefault();
path = Regex.Escape(path);
path2 = Regex.Escape(path2);
Regex rx = new Regex(path);
var a = Regex.Match(path.Split('\\').Last().ToString(), $"{fn}");
//Example A works if I split and match on just the file name.
var b = Regex.Match(path, $"{rx}");
//Example B does not work, even though it's a regex object.
var c = Regex.Match(path, $"{{path}}");
//Example C I've tried one, two, and three sets of parenthesis with no luck
var d = Regex.Match(path,path);
// Even a direct variable to variable match returns 0 results.
You seem to have it right in the last example, so perhaps the issue is that you're expecting a bool result instead of a Match result?
Hopefully this small example helps:
int a = 123;
string b = "abc";
string toMatch = "123 and abc";
var result = Regex.Match(toMatch, $"{a}.*{b}");
if (result.Success)
{
Console.WriteLine("Found a match!");
}
Related
I have string
a = "{key1}|{key2}_{key3}-{key4}"
I have another string
b = "abc|qwe_tue-pqr"
I need the output to be as to get values of
key1="abc", key2="qwe", key3="tue" and key4="pqr"
If the use case is as simple as presented you could perhaps transform a into a regex with named capturing groups:
var r = new Regex(Regex.Escape(a).Replace("\\{","(?<").Replace("}",">[a-z]+)"));
This turns a into a regex like (the | delimiter needed escaping):
(?<key1>[a-z]+)\|(?<key2>[a-z]+)_(?<key3>[a-z]+)-(?<key4>[a-z]+)
You can then get the matches and print them:
var m = r.Match(b);
foreach(Group g in m.Groups){
Console.WriteLine(g.Name + "=" + g.Value);
}
key1=abc
key2=qwe
key3=tue
key4=pqr
I can't promise it will reliably process everything you throw into it, based on the very limited input example, but it should give you the idea for a start on the process
Pretty sure we all do string.format and define some string in a specifed format.
I have a string which is always formatted in a way like this:
const string myString = string.Format("pt:{0}-first:{1}", inputString);
To get {0}, I can always check for pt:{ and read till }.
But what is the best/recommended way to extract {0} & {1} from the above variable myString ?
A Regex version of answer, but again, assuming your input doesnt contain '-'
var example = = "pt:hello-first:23";
var str = "pt:(?<First>[^-]+)-first:(?<Second>[^%]+)";
var match = new Regex(str).Match(example);
var first = match.Groups["First"].Value;
var second = match.Groups["Second"].Value;
It might be a good idea that you define what your variable can/cannot contain.
Not sure if this is the best way to do it, but it's the most obvious:
string example = "pt:123-first:456";
var split = example.Split('-');
var pt = split[0].Substring(split[0].IndexOf(':') + 1);
var first = split[1].Substring(split[1].IndexOf(':') + 1);
As Shawn said, if you can guarantee that the variables wont contain either : or - this will be adequate.
(Calculator program)count in one step with math basic order
if there is a string = "5+2*6/9"(which is user input) how to get number 2 and 6?
i've been trying with split but if there is no '+' it fail :(
here is my code atm
string[] a = kalimat.Split('*');
string[] a1 = a[0].Split('+');
string[] a2 = a1[a1.Count() - 1].Split('-');
string[] b1 = a[1].Split('+');
string[] b2 = b1[0].Split('-');
ang1 = a2[a2.Count() - 1];
ang2 = b2[0];
angka1 = Convert.ToDouble(ang1);
angka2 = Convert.ToDouble(ang2);
hasil = angka1 * angka2;
any idea guys?
If you're input expression is always in the form: "[some number]+[first value you want to return]*[second value you want to return]" then this should work for you:
var reg = new System.Text.RegularExpressions.Regex(#"\d\+(\d)\*(\d)");
var result = reg.Match("5+2*6/9");
var first = result.Groups[1];
var second = result.Groups[2];
You can of course tweak the regular expression search pattern to suit your needs.
Parsing arbitrary mathematical expression is not a trivial task. If this isn't a homework that require you to do the parsing by hand, I would suggest to find a library for doing the task, like NCalc for example.
You can install it from Nuget, and use the following simple code :
var kalimat = "5+2*6/9";
var hasil = new NCalc.Expression(kalimat).Evaluate();
Console.WriteLine(hasil);
Selamat mencoba :)
I am trying to process a report from a system which gives me the following code
000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}
I need to extract the values between the curly brackets {} and save them in to variables. I assume I will need to do this using regex or similar? I've really no idea where to start!! I'm using c# asp.net 4.
I need the following variables
param1 = 000
param2 = GEN
param3 = OK
param4 = 1 //Q
param5 = 1 //M
param6 = 002 //B
param7 = 3e5e65656-e5dd-45678-b785-a05656569e //I
I will name the params based on what they actually mean. Can anyone please help me here? I have tried to split based on spaces, but I get the other garbage with it!
Thanks for any pointers/help!
If the format is pretty constant, you can use .NET string processing methods to pull out the values, something along the lines of
string line =
"000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}";
int start = line.IndexOf('{');
int end = line.IndexOf('}');
string variablePart = line.Substring(start + 1, end - start);
string[] variables = variablePart.Split(' ');
foreach (string variable in variables)
{
string[] parts = variable.Split('=');
// parts[0] holds the variable name, parts[1] holds the value
}
Wrote this off the top of my head, so there may be an off-by-one error somewhere. Also, it would be advisable to add error checking e.g. to make sure the input string has both a { and a }.
I would suggest a regular expression for this type of work.
var objRegex = new System.Text.RegularExpressions.Regex(#"^(\d+)=\[([A-Z]+)\] ([A-Z]+) \{Q=(\d+) M=(\d+) B=(\d+) I=([a-z0-9\-]+)\}$");
var objMatch = objRegex.Match("000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}");
if (objMatch.Success)
{
Console.WriteLine(objMatch.Groups[1].ToString());
Console.WriteLine(objMatch.Groups[2].ToString());
Console.WriteLine(objMatch.Groups[3].ToString());
Console.WriteLine(objMatch.Groups[4].ToString());
Console.WriteLine(objMatch.Groups[5].ToString());
Console.WriteLine(objMatch.Groups[6].ToString());
Console.WriteLine(objMatch.Groups[7].ToString());
}
I've just tested this out and it works well for me.
Use a regular expression.
Quick and dirty attempt:
(?<ID1>[0-9]*)=\[(?<GEN>[a-zA-Z]*)\] OK {Q=(?<Q>[0-9]*) M=(?<M>[0-9]*) B=(?<B>[0-9]*) I=(?<I>[a-zA-Z0-9\-]*)}
This will generate named groups called ID1, GEN, Q, M, B and I.
Check out the MSDN docs for details on using Regular Expressions in C#.
You can use Regex Hero for quick C# regex testing.
You can use String.Split
string[] parts = s.Split(new string[] {"=[", "] ", " {Q=", " M=", " B=", " I=", "}"},
StringSplitOptions.None);
This solution breaks up your report code into segments and stores the desired values into an array.
The regular expression matches one report code segment at a time and stores the appropriate values in the "Parsed Report Code Array".
As your example implied, the first two code segments are treated differently than the ones after that. I made the assumption that it is always the first two segments that are processed differently.
private static string[] ParseReportCode(string reportCode) {
const int FIRST_VALUE_ONLY_SEGMENT = 3;
const int GRP_SEGMENT_NAME = 1;
const int GRP_SEGMENT_VALUE = 2;
Regex reportCodeSegmentPattern = new Regex(#"\s*([^\}\{=\s]+)(?:=\[?([^\s\]\}]+)\]?)?");
Match matchReportCodeSegment = reportCodeSegmentPattern.Match(reportCode);
List<string> parsedCodeSegmentElements = new List<string>();
int segmentCount = 0;
while (matchReportCodeSegment.Success) {
if (++segmentCount < FIRST_VALUE_ONLY_SEGMENT) {
string segmentName = matchReportCodeSegment.Groups[GRP_SEGMENT_NAME].Value;
parsedCodeSegmentElements.Add(segmentName);
}
string segmentValue = matchReportCodeSegment.Groups[GRP_SEGMENT_VALUE].Value;
if (segmentValue.Length > 0) parsedCodeSegmentElements.Add(segmentValue);
matchReportCodeSegment = matchReportCodeSegment.NextMatch();
}
return parsedCodeSegmentElements.ToArray();
}
I have a string and need to replace some content based on certain substrings appearing in the string. e.g. a sample string might be
(it.FirstField = "fred" AND it.SecondField = True AND it.ThirdField = False AND it.FifthField = True)
and I want to transform it to:
(it.FirstField = "fred" AND it.SecondField = 'Y' AND it.ThirdField = 'N' AND it.FifthField = True)
i.e. if the substring appears in the string, I want to change the True to 'Y' and the False to 'N', but leave any other True/False values intact.
I have an array of substrings to look for:
string[] booleanFields = { "SecondField", "ThirdField", "FourthField" };
I can use something like if (booleanFields.Any(s => inputString.Contains(s))) to find out if the string contains any of the keywords, but what's the best way to perform the replacement?
Thanks.
In the words of clipit - it looks like you are trying to parse SQL, would you like some help with that?
You can try and do this via string manipulation, but you are going to run into problems - think about what would happen if you replaced "fred" with something else, perhaps:
(it.FirstField = "it.SecondField = True" AND it.SecondField = True)
I'm loathed to recommend it (because it's probably quite difficult), but the correct way to do this is to parse the SQL and manipulate the parsed expression - see Parsing SQL code in C# for what looks like an approach that could make this relatively straightfoward.
It's probably not the best answer due to the two very similar lines (one for true/one for false), but this works and is fairly neat for a Regex (with .Dump() ready for LINQPad paste).
It does however assume that you want to replace every ".FieldName = True" within your content (which will include cases where this format is enclosed in quotes as a string value).
void Main()
{
List<string> booleanFields = new List<string> { "SecondField", "ThirdField", "FourthField" };
string s = #"(it.FirstField = ""fred"" AND it.SecondField = True AND it.ThirdField = False AND it.FifthField = True)";
booleanFields.ForEach(bf => s = Regex.Replace(s, String.Format(#"[.]{0}[ ]*=[ ]*True", bf), String.Format(".{0} = 'Y'", bf)));
booleanFields.ForEach(bf => s = Regex.Replace(s, String.Format(#"[.]{0}[ ]*=[ ]*False", bf), String.Format(".{0} = 'N'", bf)));
s.Dump();
}