Reputation: 3611
How can I specify to only match the first occurrence of a regular expression in C# using Regex method?
Here's an example:
string text = @"<link href=""/_layouts/OracleBI/OracleBridge.ashx?RedirectURL=res/sk_oracle10/b_mozilla_4/common.css"" type=""text/css"" rel=""stylesheet""></link></link>";
string pattern = @"(<link).+(link>)";
Regex myRegex = new Regex(pattern, RegexOptions.IgnoreCase);
Match m = myRegex.Match(text); // m is the first match
while (m.Success)
{
// Do something with m
Console.Write(m.Value + "\n");
m = m.NextMatch(); // more matches
}
Console.Read();
I would like this to only replace up to the first <\link>
. And then also do the same for the rest of these matches.
Upvotes: 34
Views: 62176
Reputation: 116977
Regex.Match(myString) returns the first match it finds.
Subsequent calls to NextMatch()
on the resultant object from Match()
will continue to match the next occurrences, if any.
For example:
string text = "my string to match";
string pattern = @"(\w+)\s+";
Regex myRegex = new Regex(pattern, RegexOptions.IgnoreCase);
Match m = myRegex.Match(text); // m is the first match
while (m.Success)
{
// Do something with m
m = m.NextMatch(); // more matches
}
Upvotes: 48
Reputation: 17
try this
string text = @"<link href=""/_layouts/OracleBI/OracleBridge.ashx?RedirectURL=res/sk_oracle10/b_mozilla_4/common.css"" type=""text/css"" rel=""stylesheet""> </link></link>";
string pattern = @"(<link).+(link>)";
Regex myRegex = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = myRegex.Matches(text);
foreach (Match m in matches) {
Console.Write(m.Value + "\n");
}
Console.Read();
Upvotes: 0
Reputation: 1577
string text = @"<link href=""/_layouts/OracleBI/OracleBridge.ashx?RedirectURL=res/sk_oracle10/b_mozilla_4/common.css"" type=""text/css"" rel=""stylesheet""></link></link>";
string pattern = @"(<link).+(link>)";
//Regex myRegex = new Regex(pattern, RegexOptions.IgnoreCase);
//Match m = myRegex.Match(text); // m is the first match
Match m = Regex.Match(text, pattern, RegexOptions.IgnoreCase);
/*while (m.Success)
{
// Do something with m
Console.Write(m.Value + "\n");
m = m.NextMatch(); // more matches
}*/
// use if statement; you only need 1st match
if (m.Success)
{
// Do something with m.Value
// m.Index indicates its starting location in text
// m.Length is the length of m.Value
// using m.Index and m.Length allows for easy string replacement and manipulation of text
}
Console.Read();
Upvotes: 3
Reputation: 3102
Maybe a little over-simplified, but if you get a collection of matches back and want to get the first occurrence you could look at the Match.Index
property to find the lowest index.
Here's the MSDN documentation on it.
If it is just a scope issue, then I agree with Rich's comment - you need to use non-greedy modifiers to stop your expression from 'eating' too much.
Upvotes: 0
Reputation: 36806
I believe you just need to add a lazy qualifier on the first example. Whenever a wild card is "eating too much", you either need a lazy qualifier on the wild card or, in a more complicated scenario, look ahead. Add a lazy qualifier at the top (.+?
in place of .+
), and you should be good.
Upvotes: 35