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();
}
Related
I have 2 strings, one is main string and other is pattern string to be replaced. I want to replace the some part of main string with pattern string only if particular pattern is matched in main string.
Example:
string mainstring = "[def].[ijk] = [abc].[def].[ijk]";
string pattern = "[lmn].[def].[ijk]";
i want final string as
[lmn].[def].[ijk] = [abc].[def].[ijk]
i.e. if only 2 part is there in string than only replace not for 3 parts
i am using:
mainstring = mainstring.Replace("[def].[ijk]",pattern);
but it replaces as,
[lmn].[def].[ijk] = [abc].[lmn].[def].[ijk]
^-------+-------^
|
+-- don't replace here
but I want as
[lmn].[def].[ijk] = [abc].[def].[ijk]
EDIT: Additional rule for the replacement:
You can touch left hand side or right hand side but the pattern should be alone without anything at before or after.
I am trying to follow this rule:
i.e. if only 2 part is there in string than only replace not for 3 parts
(interpreting it as replace only if the matching pattern is not inbetween other parts, or: neither preceded nor follwed by a .)
This regular expression should satisfy this rule above:
string mainstring = "[def].[ijk] = [abc].[def].[ijk]";
// will replace only right side
//string mainstring = "[abc].[def].[ijk] = [def].[ijk]";
string replacement = "[lmn].[def].[ijk]";
string pattern = #"(?<!\.)\[def\].\[ijk\](?!\.)";
string output = Regex.Replace(mainstring, pattern, replacement);
EDIT:
if you need to transform you basic pattern into a regex format replace both parentheses:
string searchPattern = "[def].[ijk]";
searchPattern = searchPattern.Replace("[", #"\[").Replace("]", #"\]");
and place the result in between the look ahead and look behind pattern:
string pattern = #"(?<!\.)" + searchPattern + #"(?!\.)";
Explanation:
(?<!\.): the pattern is called negative lookahead. It will match only if the preceding character is not a . (dot)
(?!\.): the pattern is called negative lookbehind. It will match only if the following character is not a . (dot)
the replacement of [ ] to \[ \] is necessary because regex treats the parentheses as an interval or group and matches every character between the parentheses. Like [0-9] will match any digit between 0 and 9. But if you use an escape sequence #"\[0-9\]" it will take the parentheses as a character and match the pattern "[0-9]". I hope it became a little clearer
does this work for you?
string mainstring = "[def].[ijk] = [abc].[def].[ijk]";
string leftFillWith = "[lmn].[def].[ijk]";
string pattern = #"((\[lmn\]).)?((\[def\]).)?(\[ijk\])? =";
var expected= Regex.Replace(mainstring, pattern,match=> leftFillWith+" =" );
if only two parts are accepted:
string mainstring = "[def].[ijk] = [abc].[def].[ijk]";
string leftFillWith = "[lmn].[def].[ijk]";
// string pattern = #"((\[lmn\]).)?((\[def\]).)?(\[ijk\])? ="; //if any number of parts is accepted on left
string pattern = #"(\[def\]\.\[ijk\])(\s)+="; //if only two parts are accepted
string expected = Regex.IsMatch(mainstring,pattern)? Regex.Replace(mainstring, pattern, match => leftFillWith + " ="):mainstring;
Not good but work;
string mainstring = "[def].[ijk] = [abc].[def].[ijk]";
string pattern = "[lmn].[def].[ijk]";
string search ="[def].[ijk]";
string mainstring3 = "";
string[] mainstring2 = mainstring.Split(' ');
for (int i = 0; i < mainstring2.Length; i++)
{
if (mainstring2[i] == search)
{
mainstring2[i] = pattern;
}
if (i < mainstring2.Length - 1)
{
mainstring3 += mainstring2[i] + " ";
}
else
{
mainstring3 += mainstring2[i];
}
}
mainstring = mainstring3;
}
private String pattern = #"^{(.*)|(.*)}$";
ret = groups[0].Captures.Count.ToString(); // returns 1
isn't it should return 2 captures? because I have two () in my RegExp?
my string for example:
{test1 | test2}
the first capture should be test1 and the secnd test2, but I get the whole string in return and the captures count is 1 why is that?
UPDATE:
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = rgx.Matches(_sourceString);
String ret = "";
foreach (Match match in matches)
{
GroupCollection groups = match.Groups;
ret = groups[0].Captures[0].Value;
}
return ret; //returns the whole string, but I've expected 'test1'
| has a special meaning in regular expression. A|B matches A or B.
To match | literally, you need to escape it:
#"^{(.*)\|(.*)}$";
string subject = null;
string toFind = "["+emailFound+"]([.20])";
Match match = Regex.Match(messageText, toFind, RegexOptions.IgnoreCase);
if (match.Success)
{
subject = match.Value;
}
MessageBox.Show(subject);
This is code I have so far, I'm really new at regex and not quite sure how it works. How would I get the first 20 characters after "emailFound"
Thanks
No more errors, but now it's just not finding anything after the emailFound...
That's because you need to get the Group value after you check the match instance.
string toFind = Regex.Escape(emailFound) + "(?s)(.{20})";
Match match = Regex.Match(messageText, toFind);
if (match.Success) {
subject = match.Groups[1].Value; // Get the Group value
}
See live demo
You can try this:
string toFind = Regex.Escape(emailFound)+"(?s)(.{20})";
(?s) allows the dot to match newlines (you can remove it and add the RegexOptions.SingleLine in the Match method.)
.{20} twenty characters
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))));
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);
}