I am just starting to learn about regular expressions. What I need is to check for a slash followed by "C" followed by three uppercase characters / numbers and then another slash followed by anything.
var a = "/C001/dsafalkdsfjsadfj";
var b = "/CXXX/adsf";
Can someone tell me how I can do a check for this within an if test?
if ( regular expression ) {}
try that :
you wrote :
and then another slash followed by anything
which is not your example , but anyway : (according to the sentence )
\/C[A-Z0-9]{3}\/$
(according to the example : )
\/C[A-Z0-9]{3}\/[a-z]$
(according to your response : )
\/C[A-Z0-9]{3}\/
Regex regex = new Regex (#"\/C[A-Z0-9]{3}\/$");
MatchCollection matches = regex.Matches(yourstring);
if matches.Count>0...
string input = "/C001/dsafalkdsfjsadfj";
var pattern = #"/C[A-Z0-9]{3}/.*";
var matches = Regex.Matches(input, pattern);
string result = "";
for (int i = 0; i < matches.Count; i++)
{
result += "match " + i + ",value:" + matches[i].Value + "\n";
}
Console.WriteLine("Result:\n"+result);
Related
I have a input string like -
abbdabab
How to replace only the 2nd, 3rd and subsequent occurances of the substring "ab" with any random string like "x" keeping the original string intact. Example in this case -
1st Output - xbdabab 2nd Output - abbdxab 3rd Output - abbdabx and so on...
I have tried using Regex like -
int occCount = Regex.Matches("abbdabab", "ab").Count;
if (occCount > 1)
{
for (int i = 1; i <= occCount; i++)
{
Regex regReplace = new Regex("ab");
string modifiedValue = regReplace.Replace("abbdabab", "x", i);
//decodedMessages.Add(modifiedValue);
}
}
Here I am able to get the 1st output when the counter i value is 1 but not able to get the subsequent results. Is there any overloaded Replace method which could achieve this ? Or Can anyone help me in pointing where I might have gone wrong?
You can try IndexOf instead of regular expressions:
string source = "abbdabab";
string toFind = "ab";
string toSet = "X";
for (int index = source.IndexOf(toFind);
index >= 0;
index = source.IndexOf(toFind, index + 1)) {
string result = source.Substring(0, index) +
toSet +
source.Substring(index + toFind.Length);
Console.WriteLine(result);
}
Outcome:
Xbdabab
abbdXab
abbdabX
You can use a StringBuilder:
string s = "abbdabab";
var matches = Regex.Matches(s, "ab");
StringBuilder sb = new StringBuilder(s);
var m = matches[0]; // 0 for first output, 1 for second output, and so on
sb.Remove(m.Index, m.Length);
sb.Insert(m.Index, "x");
var result = sb.ToString();
Console.WriteLine(result);
You may use a dynamically built regex to be used with regex.Replace directly:
var s = "abbdabab";
var idx = 1; // First = 1, Second = 2
var search = "ab";
var repl = "x";
var pat = new Regex($#"(?s)((?:{search}.*?){{{idx-1}}}.*?){search}"); // ((?:ab.*?){0}.*?)ab
Console.WriteLine(pat.Replace(s, $"${{1}}{repl}", 1));
See the C# demo
The pattern will look like ((?:ab.*?){0}.*?)ab and will match
(?s) - RegexOptions.Singleline to make . also match newlines
((?:ab.*?){0}.*?) - Group 1 (later, this value will be put back into the result with ${1} backreference)
(?:ab.*?){0} - 0 occurrences of ab followed with any 0+ chars as few as possible
.*? - any 0+ chars as few as possible
ab - the search string/pattern.
The last argument to pat.Replace is 1, so that only the first occurrence could be replaced.
If search is a literal text, you need to use var search = Regex.Escape("a+b");.
If the repl can have $, add repl = repl.Replace("$", "$$");.
For example I have such string:
ex250-r-ninja-08-10r_
how could I change it to such string?
ex250 r ninja 08-10r_
as you can see I change all - to space, but didn't change it where I have XX-XX part... how could I do such string replacement in c# ? (also string could be different length)
I do so for -
string correctString = errString.Replace("-", " ");
but how to left - where number pattern XX-XX ?
You can use regular expressions to only perform substitutions in certain cases. In this case, you want to perform a substitution if either side of the dash is a non-digit. That's not quite as simple as it might be, but you can use:
string ReplaceSomeHyphens(string input)
{
string result = Regex.Replace(input, #"(\D)-", "${1} ");
result = Regex.Replace(result, #"-(\D)", " ${1}");
return result;
}
It's possible that there's a more cunning way to do this in a single regular expression, but I suspect that it would be more complicated too :)
A very uncool approach using a StringBuilder. It'll replace all - with space if the two characters before and the two characters behind are not digits.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
bool replace = false;
char c = text[i];
if (c == '-')
{
if (i < 2 || i >= text.Length - 2) replace = true;
else
{
bool leftDigit = text.Substring(i - 2, 2).All(Char.IsDigit);
bool rightDigit = text.Substring(i + 1, 2).All(Char.IsDigit);
replace = !leftDigit || !rightDigit;
}
}
if (replace)
sb.Append(' ');
else
sb.Append(c);
}
Since you say you won't have hyphens at the start of your string then you need to capture every occurrence of - that is preceded by a group of characters which contains at least one letter and zero or many numbers. To achieve this, use positive lookbehind in your regex.
string strRegex = #"(?<=[a-z]+[0-9]*)-";
Regex myRegex = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Multiline);
string strTargetString = #"ex250-r-ninja-08-10r_";
string strReplace = #" ";
return myRegex.Replace(strTargetString, strReplace);
Here are the results:
Is there any way to take a part out of a regex? Let's say I have a match for this
\s*(string)\s*(.*\()\s*(\d*)\)\s*;?(.*)
and I want to change it like this
Regex.Replace(line, #"\s*(string)\s*(.*\()\s*(\d*)\)\s*;?(.*)", "$1 $2($3) // $4", RegexOptions.IgnoreCase);
Is there any way I can grab the $4 by itself and set it equal to some string variable?
Let's say the regex match is: string (55) ;comment
In this case I'd like to get the word comment only and set it to a string without going through the String.Split function. Ultimately, though, I'd just like to get the digits between the parentheses.
There's an overload for the Replace method which takes a MatchEvaluator delegate:
string pattern = "...";
string result = Regex.Replace(line, pattern, m =>
{
int digits = 0;
string comment = m.Groups[4].Value; // $4
int.TryParse(m.Groups[3].Value, out digits); // $3
return string.Format("{0} {1}({2}) // {3}",
m.Groups[1].Value, m.Groups[2].Value, digits, comment);
}, RegexOptions.IgnoreCase);
Hope this helps.
Yes, if I understand the question correctly:
var re = new Regex(#"\s*(string)\s*(.*\()\s*(\d*)\)\s*;?(.*)");
var match = re.Match(input);
if (match.Success)
{
int i = match.Groups[4].Index;
int n = match.Groups[4].Length;
input = input.Substring(0, i) + replacementString + input.Substring(i + n);
}
I got this code below that works for single quotes.
it finds all the words between the single quotes.
but how would I modify the regex to work with double quotes?
keywords is coming from a form post
so
keywords = 'peace "this world" would be "and then" some'
// Match all quoted fields
MatchCollection col = Regex.Matches(keywords, #"'(.*?)'");
// Copy groups to a string[] array
string[] fields = new string[col.Count];
for (int i = 0; i < fields.Length; i++)
{
fields[i] = col[i].Groups[1].Value; // (Index 1 is the first group)
}// Match all quoted fields
MatchCollection col = Regex.Matches(keywords, #"'(.*?)'");
// Copy groups to a string[] array
string[] fields = new string[col.Count];
for (int i = 0; i < fields.Length; i++)
{
fields[i] = col[i].Groups[1].Value; // (Index 1 is the first group)
}
You would simply replace the ' with \" and remove the literal to reconstruct it properly.
MatchCollection col = Regex.Matches(keywords, "\\\"(.*?)\\\"");
The exact same, but with double quotes in place of single quotes. Double quotes aren't special in a regex pattern. But I usually add something to make sure I'm not spanning accross multiple quoted strings in a single match, and to accomodate double-double quote escapes:
string pattern = #"""([^""]|"""")*""";
// or (same thing):
string pattern = "\"(^\"|\"\")*\"";
Which translates to the literal string
"(^"|"")*"
Use this regex:
"(.*?)"
or
"([^"]*)"
In C#:
var pattern = "\"(.*?)\"";
or
var pattern = "\"([^\"]*)\"";
Do you want to match " or ' ?
in which case you might want to do something like this:
[Test]
public void Test()
{
string input = "peace \"this world\" would be 'and then' some";
MatchCollection matches = Regex.Matches(input, #"(?<=([\'\""])).*?(?=\1)");
Assert.AreEqual("this world", matches[0].Value);
Assert.AreEqual("and then", matches[1].Value);
}
I have a part of a URL like this:
/home/{value1}/something/{anotherValue}
Now i want to replace all between the brackets with values from a string-array.
I tried this RegEx pattern: \{[a-zA-Z_]\} but it doesn't work.
Later (in C#) I want to replace the first match with the first value of the array, second with the second.
Update: The /'s cant be used to separate. Only the placeholders {...} should be replaced.
Example: /home/before{value1}/and/{anotherValue}
String array: {"Tag", "1"}
Result: /home/beforeTag/and/1
I hoped it could works like this:
string input = #"/home/before{value1}/and/{anotherValue}";
string pattern = #"\{[a-zA-Z_]\}";
string[] values = {"Tag", "1"};
MatchCollection mc = Regex.Match(input, pattern);
for(int i, ...)
{
mc.Replace(values[i];
}
string result = mc.GetResult;
Edit:
Thank you Devendra D. Chavan and ipr101,
both solutions are greate!
You can try this code fragment,
// Begin with '{' followed by any number of word like characters and then end with '}'
var pattern = #"{\w*}";
var regex = new Regex(pattern);
var replacementArray = new [] {"abc", "cde", "def"};
var sourceString = #"/home/{value1}/something/{anotherValue}";
var matchCollection = regex.Matches(sourceString);
for (int i = 0; i < matchCollection.Count && i < replacementArray.Length; i++)
{
sourceString = sourceString.Replace(matchCollection[i].Value, replacementArray[i]);
}
[a-zA-Z_] describes a character class. For words, you'll have to add * at the end (any number of characters within a-zA-Z_.
Then, to have 'value1' captured, you'll need to add number support : [a-zA-Z0-9_]*, which can be summarized with: \w*
So try this one : {\w*}
But for replacing in C#, string.Split('/') might be easier as Fredrik proposed. Have a look at this too
You could use a delegate, something like this -
string[] strings = {"dog", "cat"};
int counter = -1;
string input = #"/home/{value1}/something/{anotherValue}";
Regex reg = new Regex(#"\{([a-zA-Z0-9]*)\}");
string result = reg.Replace(input, delegate(Match m) {
counter++;
return "{" + strings[counter] + "}";
});
My two cents:
// input string
string txt = "/home/{value1}/something/{anotherValue}";
// template replacements
string[] str_array = { "one", "two" };
// regex to match a template
Regex regex = new Regex("{[^}]*}");
// replace the first template occurrence for each element in array
foreach (string s in str_array)
{
txt = regex.Replace(txt, s, 1);
}
Console.Write(txt);