How to find match letter in (mystring after match letter) - c#

I have need to check complex property in c#. I get the complex property List of string are:
EmployeeID
contactNo
Employee.FirstName // these is complex property
Employee.LastName // these is complex property
I know about regex.match() but i have doubt about how to check the string in after placed in dot value that means i want to check in Employee and after placed dot value. can you please help any idea about this?

Using regex, you can match complex properties like this:
List<string> properties = new List<string>()
{
"EmployeeID",
"contactNo",
"Employee.FirstName", // these is complex property
"Employee.LastName", // these is complex property
};
Regex rgx = new Regex(#"Employee\.(.*)");
var results = new List<string>();
foreach(var prop in properties)
{
foreach (var match in rgx.Matches(prop))
{
results.Add(match.ToString());
}
}
If you just want what is after the . (FirstName and LastName), replace the pattern like this:
Regex rgx = new Regex(#"(?<=Employee\.)\w*");

Without regex:
List<string> listofstring = { .... };
List<string> results = new List<string>();
const string toMatch = "Employee.";
foreach (string str in listofstring)
{
if (str.StartsWith(toMatch))
{
results.Add(str.Substring(toMatch.Length));
}
}
If you just need to match .
List<string> listofstring = { .... };
List<string> results = new List<string>();
const string toMatch = ".";
int index = -1;
foreach (string str in listofstring)
{
index = str.IndexOf(toMatch);
if(index >= 0)
{
results.Add(str.Substring(index + 1));
}
}

Related

Regex alternative for extracting numeric and non-numeric strings

Using the below expression, I'm able to get the expected output and extract numbers or string and split to a string array.
Regex _re = new Regex(#"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);
_re.Split("2323dfdf233fgfgfg ddfdf334").Dump(); //string can be any alphanumeric start with
How to achieve the same thing without using Regex? Do I need to parse each char and segregate? I have a large array of text which needs to be processed to extract but I cannot use regex as inputs provided.
For a Linq solution, you can combine the use of Enumerable.Skip() and Enumerable.TakeWhile() while checking for char.IsDigit() to determine whether the character is a digit or not. For example:
string inputString = "2323dfdf233fgfgfg ddfdf334";
var list = new List<string>();
int usedLength = 0;
while (usedLength < inputString.Length)
{
bool isDigit = char.IsDigit(inputString[usedLength]);
string item = string.Concat(inputString.Skip(usedLength).
TakeWhile((c) => char.IsDigit(c) == isDigit));
usedLength += item.Length;
list.Add(item);
};
Then you can easily iterate through the list:
foreach (string item in list)
Console.WriteLine(item);
Output:
2323
dfdf
233
fgfgfg ddfdf
334
This solution is fast enough. Check with larger strings.
string str = "2323dfdf233fgfgfg ddfdf334";
var strings = new List<string>();
var sb = new StringBuilder();
var lastCharIsNumber = char.IsDigit(str[0]);
foreach (var c in str) {
if (char.IsDigit(c) ) {
if (!lastCharIsNumber) {
strings.Add(sb.ToString());
sb.Clear();
}
lastCharIsNumber = true;
}
else {
if (lastCharIsNumber) {
strings.Add(sb.ToString());
sb.Clear();
}
lastCharIsNumber = false;
}
sb.Append(c);
}
strings.Add(sb.ToString());
strings.Dump();

Using lambda expression to select array element where it matches in string

I am trying to select an element in array, that matches something in a string.
For example:
string[] splitChar = new string[] { "+=", "-=" };
string content = "5+=2";
So i want to check if content, contains something from splitChar, and if it does then select the value so it can be assigned to a string variable.
Lambdas and LINQ would be overkill for this. You can just do a simple foreach:
string match = "";
foreach (var str in splitChar)
{
if (content.Contains(str))
{
match = str;
break;
}
}
if (!String.IsNullOrEmpty(match))
{
// Do whatever with `match`
}
If you really wanted to use LINQ, though, FirstOrDefault would be your best bet:
string match = splitChar.FirstOrDefault(s => content.Contains(s));
if (!String.IsNullOrEmpty(match))
{
// Do whatever with `match`
}
Have you tried checking with FirstOrDefault like the following?
string[] splitChar = new string[] { "+=", "-=" };
string content = "5+=2";
var stringPresent = splitChar.FirstOrDefault(x=>content.Contains(x));
if(String.IsNullOrEmpty(stringPresent))
Console.WriteLine("Not found");
else
Console.WriteLine(stringPresent);
Check this Example

Regex replace multiple groups with wildcards

I found an answer when we do not use wildcard characters. So question is - how to perform multiple replaces by regex. This code shows what i want to do
internal class Program
{
private static void Main(string[] args)
{
var rules = new Dictionary<string, string>
{
{#"F\S+", "Replace 1"},
{#"\S+z", "Replace 2"},
};
string s = "Foo bar baz";
string result = ProcessText(s, rules);
Console.WriteLine(result);
}
private static string ProcessText(string input, Dictionary<string, string> rules)
{
string[] patterns = rules.Keys.ToArray();
string pattern = string.Join("|", patterns);
return Regex.Replace(input, pattern, match =>
{
int index = GetMatchIndex(match);
return rules[patterns[index]];
});
}
private static int GetMatchIndex(Match match)
{
int i = 0;
foreach (Match g in match.Groups)
{
if (g.Success)
return i;
i++;
}
throw new Exception("Never throws");
}
}
but match.Groups.Count is always 1.
I'm looking for the fastest alternative. Perhaps, it shouldn't use regexes.
I don't understand why are you concatenating patterns and then performin so many searches in an array.
Can't you just apply each pattern individually like this?
var rules = new Dictionary<string, string>
{
{#"F\S+", "Replace 1"},
{#"\S+z", "Replace 2"},
};
string s = "Foo bar baz";
var result = rules.Aggregate(s, (seed, rule) => Regex.Replace(seed, rule.Key, m => rule.Value));
EDIT
Your match.Groups.Count is always one because there are no groups defined in your matches and the values is the entire matched string as described on MSDN. In other words, your GetMatchIndex method does nothing.
You could try transforming your patterns into named groups like this:
var patterns = rules.Select((kvp, index) => new
{
Key = String.Format("(?<{0}>{1})", index, kvp.Key),
Value = kvp.Value
};
Having this array, in GetMatchIndex method you'd just parse the group name as being the index of the matched pattern:
private static int GetMatchIndex(Regex regex, Match match)
{
foreach(var name in regex.GetGroupNames())
{
var group = match.Groups[name];
if(group.Success)
return int.Parse(name); //group name is a number
}
return -1;
}
Now, you can use it like this:
var pattern = String.Join("|", patterns.Select(x => x.Key));
var regex = new Regex(pattern);
return regex.Replace(input, pattern, m =>
{
var index = GetMatchIndex(regex, m);
return patterns[index].Value;
});
To make it (probably way) faster extract
var keyArray = rules.Keys.ToArray()
before you use it in:
return Regex.Replace(input, pattern, match =>
{
int index = GetMatchIndex(match);
return rules[keyArray[index]];
});

Extracting variable number of token pairs from a string to a pair of arrays

Here is the requirement.
I have a string with multiple entries of a particular format. Example below
string SourceString = "<parameter1(value1)><parameter2(value2)><parameter3(value3)>";
I want to get the ouput as below
string[] parameters = {"parameter1","parameter2","parameter3"};
string[] values = {"value1","value2","value3"};
The above string is just an example with 3 pairs of parameter values. The string may have 40, 52, 75 - any number of entries (less than 100 in one string).
Like this I have multiple strings in an array. I want to do this operation for all the strings in the array.
Could any one please advice how to achieve this? I'm a novice in c#.
Is using regex a better solution or is there any other method?
Any help is much appreciated.
If you didn't like RegEx's you could do something like this:
class Program
{
static void Main()
{
string input = "<parameter1(value1)>< parameter2(value2)>";
string[] Items = input.Replace("<", "").Split('>');
List<string> parameters = new List<string>();
List<string> values = new List<string>();
foreach (var item in Items)
{
if (item != "")
{
KeyValuePair<string, string> kvp = GetInnerItem(item);
parameters.Add(kvp.Key);
values.Add(kvp.Value);
}
}
// if you really wanted your results in arrays
//
string[] parametersArray = parameters.ToArray();
string[] valuesArray = values.ToArray();
}
public static KeyValuePair<string, string> GetInnerItem(string item)
{
//expects parameter1(value1)
string[] s = item.Replace(")", "").Split('(');
return new KeyValuePair<string, string>(s[0].Trim(), s[1].Trim());
}
}
It might be a wee bit quicker than the RegEx method but certainly not as flexible.
You could use RegEx class in combination with an expression to parse the string and generate these arrays by looping through MatchCollections.
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx
This does it:
string[] parameters = null;
string[] values = null;
// string SourceString = "<parameter1(value1)><parameter2(value2)><parameter3(value3)>";
string SourceString = #"<QUEUE(C2.BRH.ARB_INVPUSH01)><CHANNEL(C2.MONITORING_CHANNEL)><QMGR(C2.MASTER_NA‌​ME.TRACKER)>";
// string regExpression = #"<([^\(]+)[\(]([\w]+)";
string regExpression = #"<([^\(]+)[\(]([^\)]+)";
Regex r = new Regex(regExpression);
MatchCollection collection = r.Matches(SourceString);
parameters = new string[collection.Count];
values = new string[collection.Count];
for (int i = 0; i < collection.Count; i++)
{
Match m = collection[i];
parameters[i] = m.Groups[1].Value;
values[i] = m.Groups[2].Value;
}

Extracting strings in .NET

I have a string that looks like this:
var expression = #"Args("token1") + Args("token2")";
I want to retrieve a collection of strings that are enclosed in Args("") in the expression.
How would I do this in C# or VB.NET?
Regex:
string expression = "Args(\"token1\") + Args(\"token2\")";
Regex r = new Regex("Args\\(\"([^\"]+)\"\\)");
List<string> tokens = new List<string>();
foreach (var match in r.Matches(expression)) {
string s = match.ToString();
int start = s.IndexOf('\"');
int end = s.LastIndexOf('\"');
tokens.add(s.Substring(start + 1, end - start - 1));
}
Non-regex (this assumes that the string in the correct format!):
string expression = "Args(\"token1\") + Args(\"token2\")";
List<string> tokens = new List<string>();
int index;
while (!String.IsNullOrEmpty(expression) && (index = expression.IndexOf("Args(\"")) >= 0) {
int start = expression.IndexOf('\"', index);
string s = expression.Substring(start + 1);
int end = s.IndexOf("\")");
tokens.Add(s.Substring(0, end));
expression = s.Substring(end + 2);
}
There is another regular expression method for accomplishing this, using lookahead and lookbehind assertions:
Regex regex = new Regex("(?<=Args\\(\").*?(?=\"\\))");
string input = "Args(\"token1\") + Args(\"token2\")";
MatchCollection matches = regex.Matches(input);
foreach (var match in matches)
{
Console.WriteLine(match.ToString());
}
This strips away the Args sections of the string, giving just the tokens.
If you want token1 and token2, you can use following regex
input=#"Args(""token1"") + Args(""token2"")"
MatchCollection matches = Regex.Matches(input,#"Args\(""([^""]+)""\)");
Sorry, If this is not what you are looking for.
if your collection looks like this:
IList<String> expression = new List<String> { "token1", "token2" };
var collection = expression.Select(s => Args(s));
As long as Args returns the same type as the queried collection type this should work okay
you can then iterate over the collection like so
foreach (var s in collection)
{
Console.WriteLine(s);
}

Categories