Regex replace with separate replacement depending on the match - c#

Suppose if I have a dictionary (word and its replacements) as :
var replacements = new Dictionary<string,string>();
replacements.Add("str", "string0");
replacements.Add("str1", "string1");
replacements.Add("str2", "string2");
...
and an input string as :
string input = #"#str is a #str is a [str1] is a &str1 #str2 one test $str2 also [str]";
Edit:
Expected output :
string0 is a string0 is string0 is string1 string2 one test string2
I want to replace all occurances of '[CharSymbol]word' with its corresponding entry/value from the dictionary.
where Charsymbol can be ##$%^&*[] .. and also ']' after the word is valid i.e. [str] .
I tried the following for replace
string input = #"#str is a #str is a [str1] is a &str1 #str2 one test $str2 also [str]";
string pattern = #"(([#$&#\[]+)([a-zA-Z])*(\])*)"; // correct?
Regex re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
// string outputString = re.Replace(input,"string0");
string newString = re.Replace(input, match =>
{
Debug.WriteLine(match.ToString()); // match is [str] #str
string lookup = "~"; // default value
replacements.TryGetValue(match.Value,out lookup);
return lookup;
});
How do i get the match as str , str1 etc. i.e. word without charsymbol.

Change your regex to this:
// Move the * inside the brackets around [a-zA-Z]
// Change [a-zA-Z] to \w, to include digits.
string pattern = #"(([#$&#\[]+)(\w*)(\])*)";
Change this line:
replacements.TryGetValue(match.Value,out lookup);
to this:
replacements.TryGetValue(match.Groups[3].Value,out lookup);
Note: Your IgnoreCase isn't necessary, since you match both upper and lower case in the regex.

Does this suit?
(?<=[##&$])(\w+)|[[\w+]]
It matches the following in your example:
#str is a #str is a [str] is a &str1 #str2 one test $str2

Try this Regex: ([#$&#\[])[a-zA-Z]*(\])?, and replace with string0
your code should be like this:
var replacements = new Dictionary<string, string>
{
{"str", "string0"},
{"str1", "string1"},
{"str2", "string2"}
};
String input="#str is a #str is a [str] is a &str #str can be done $str is #str";
foreach (var replacement in replacements)
{
string pattern = String.Format(#"([#$&#\[]){0}(\])?", replacement.Key);
var re = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
string output = re.Replace(input,
String.Format("{0}", replacement.Value));
}

Related

return string based on wildcard in c#

I have tried to find a method in c# to return a string of a wildcard match, however I can only find information on how to return if it contains the wildcard match, not the string the wildcard match represents.
For example,
var myString = "abcde werrty qweert";
var newStr = MyMatchFunction("a*e", myString);
//myString = "abcde"
How would I create MyMatchFunction? I have searched around on stackoverflow, but everything that has to do with c# and wildcard is just returning boolean values on if the string contains the wildcard string, and not the string it represents.
Have you considered using Regex?
For instance, with the pattern a.*?e, you could achieve this effect
string sample = "abcde werrty qweert";
string pattern = "a.*?e";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = rgx.Matches(sample);
foreach (Match match in matches)
Console.WriteLine(match.Value);
Which would print out
abcde
Default of wildcard search for "abcde werrty qweert" with pattern of "a*b" will returns "abcde werrty qwee", but you can use gready search for the result of "abcde".
Function for WildCard match using Regex:
public static string WildCardMatch(string wildcardPattern, string input, bool Greedy = false)
{
string regexPattern = wildcardPattern.Replace("?", ".").Replace("*", Greedy ? ".*?" : ".*");
System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(input, regexPattern,
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
return m.Success ? m.Value : String.Empty;
}
Result:
var myString = "abcde werrty qweert";
var newStr = WildCardMatch("a*e", myString);
//newStr = "abcde werrty qwee"
newStr = WildCardMatch("a*e", myString, Greedy: true);
//newStr = "abcde"

Check multiple words in a string using Contains method

I want to check multiple words in a string and want to replace them. Suppose that my string is
str= 20148(R)/(work)24553(r)
if(str.contains(("R)" || str.Contains("(work)"))
{
//Here I have to replace (R) and (Work) with space "".
// so that my string should be like this 20148/24553
}
How can check multiple words not by using loops, and in one flow.
I am new to c#. Please help me out
You don't need the if, just do:
var newStr = str.Replace("(R)"," ").Replace("(work)"," ");
If you want a space as you say or:
var newStr = str.Replace("(R)",string.Empty).Replace("(work)",string.Empty);
If you want an empty string.
Put R and r inside a character class to match both letters.
string str = "20148(R)/(work)24553(r)";
string result = Regex.Replace(str, #"\((?:[Rr]|work)\)", "");
Console.WriteLine(result);
IDEONE
OR
string str = "20148(R)/(work)24553(r)";
string result = Regex.Replace(str, #"(?i)\((?:R|work)\)", "");
Console.WriteLine(result);
IDEONE
Pattern Explanation:
(?i) (i modifier) would turn on the case-insensitive mode. So it would match both upper and lowercase letters.
\( Matches a literal ( symbol.
(?:) Non-capturing group.
R|work Matches a letter R or string work.(case-insensitive match)
\) Matches a literal ) symbol.
You could use the Regex.Replace method.
string str = "20148(R)/(work)24553(r)";
string str2 = Regex.Replace(str, "[(](?:R|work)[)]", "", RegexOptions.IgnoreCase);
Console.Writeline(str2); //prints 20148/24553
This says take the string str and match the pattern [(R|work)] and replace any instances with "" ignoring the case of the input string when doing the comparison (so it matches (R) and (r)).
With regex you can replace this
[(]\b(?:R|work)\b[)]
With empty string ""
Edit:
string str1 = "20148(R)/(work)24553(r)";
string str2 = Regex.Replace(str1, "[(]\b(?:R|work)\b[)]", "", RegexOptions.IgnoreCase);
Console.Writeline(str2);

Regex for a special string pattern on multiple levels

I need to evaluate a string pattern that is something like as given below and I am quite new at writing such complex expressions
<%(ddlValue){DropDownList}[SelectedValue]%>
// this has three part (Control Name) {Control Type} [Control Property]
I tried a whole lot of regex and other tools like RegExr but anything did not worked. I have to do this on four levels, that is as given below in the code. So here is what I have done:
string regex = "/[<%](.*?)[%>]/g"; // Regex to match "<% %>" pattern
Match mtch = Regex.Match(strQuery, regex, RegexOptions.Singleline);
string strControlName = "";
string strControlType = "";
string strControlProp = "";
if (mtch.Success)
{
string strVal = mtch.Value;
Match mtchControlName = Regex.Match(strVal, "/[(]\S)/");
// Regex to match "()" i.e. control name ("ddlValue" in above example)
if (mtchControlName.Success)//Match control Name
{
strControlName = mtchControlName.Value;
Match mtchControlType = Regex.Match(strVal, "/[{]\s[}]/");
// Regex to match "[]" i.e. control type
if (mtchControlType.Success) // Match Control Type
{
strControlType = mtchControlType.Value;
Match mtchControlProp = Regex.Match(strVal, "/[(]\S[)]/");
// Regex to match "[]" i.e. control property
if (mtchControlProp.Success) // Match Control Prop
{
strControlProp = mtchControlProp.Value;
}
}
}
}
You can do this in a single regex. Being as specific as possible, you could do this:
Regex regexObj = new Regex(
#"\( # Match (
( # Capture in group 1:
[^()]* # Any number of characters except ()s
) # End of group 1
\) # Match )
\{([^{}]*)\} # The same for {...} into group 2
\[([^\[\]]*)\] # The same for [...] into group 3",
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
Then you case use
Match matchResults = regexObj.Match(subjectString);
to get a Match object. Access the submatches via
matchResults.Groups(n).Value // insert 1, 2 or 3 for n
See it live on regex101.com.
You can use capturing groups in one expression to capture all groups together:
String input = "<%(ddlValue){DropDownList}[SelectedValue]%>";
String pattern = #"<%\((.+)\)\{(.+)\}\[(.+)\]%>";
Match m = Regex.Match(input, pattern);
if (m.Groups.Count == 4)
{
string firstpart = m.Groups[1].ToString();
string secondpart = m.Groups[2].ToString();
string thirdpart = m.Groups[3].ToString();
}
You could use named groups. It makes the code more readable.
Match m = Regex.Match(inputData, #"^<%\((?<ddlValue>[^)]+)\){(?<DropDownList>[^}]+)}\[(?<SelectedValue>[^\]]+)\]%>$");
if (m.Groups.Count == 4)
{
string firstpart = m.Groups["ddlValue"].ToString();
string secondpart = m.Groups["DropDownList"].ToString();
string thirdpart = m.Groups["SelectedValue"].ToString();
}

Regex with C#: How do I replace a string that matches a specific group

Given a regex with 2 groups:
Regex regex = new Regex("^[^{}]*(\\{([^}]*)\\})[^{}]*$"); // group 1 matches {exp} (with braces)
// group 2 matches exp (without braces)
How do I replace a match in the first group?
string inputStr = "mystring{valueToRaplace}"
string s = regex .Replace(inputStr, m => ???);
For instance I want to specify whether to match and replace {valueToRaplace} (group 1) or valueToRaplace (group 2).
I think this is what you want
Regex regex = new Regex("^[^{}]*(\\{([^}]*)\\})[^{}]*$");
string inputStr = "mystring{valueToRaplace}";
string replaceWithThis = "Replace with this";
//change m.Groups[2] to whichever index you want to replace
string final = regex.Replace(inputStr,
new MatchEvaluator(new Func<Match, string>(m => inputStr.Replace(m.Groups[2].Value, replaceWithThis))));

C# Regular Expressions, string between single quotes

string val = "name='40474740-1e40-47ce-aeba-ebd1eb1630c0'";
i want to get the text between ' quotes using Regular Expressions.
Can anyone?
Something like this should do it:
string val = "name='40474740-1e40-47ce-aeba-ebd1eb1630c0'";
Match match = Regex.Match(val, #"'([^']*)");
if (match.Success)
{
string yourValue = match.Groups[1].Value;
Console.WriteLine(yourValue);
}
Explanation of the expression '([^']*):
' -> find a single quotation mark
( -> start a matching group
[^'] -> match any character that is not a single quotation mark
* -> ...zero or more times
) -> end the matching group
You are looking to match GUID's in a string using a regular expression.
This is what you want, I suspect!
public static Regex regex = new Regex(
"(\\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-"+
"([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}{0,1})",RegexOptions.CultureInvariant|RegexOptions.Compiled);
Match m = regex.Match(lineData);
if (m.Succes)
{
...
}
This will extract the text between the first and last single quote on a line:
string input = "name='40474740-1e40-47ce-aeba-ebd1eb1630c0'";
Regex regName = new Regex("'(.*)'");
Match match = regName.Match(input);
if (match.Success)
{
string result = match.Groups[1].Value;
//do something with the result
}
You could use positive lookahead and lookbehind also,
string val = "name='40474740-1e40-47ce-aeba-ebd1eb1630c0'";
Match match = Regex.Match(val, #"(?<=')[^']*(?=')");
if (match.Success)
{
string yourValue = match.Groups[0].Value;
Console.WriteLine(yourValue);
}

Categories