Как указать только совпадение первого вхождения?
Как я могу указать только совпадение первого вхождения регулярного выражения в С# с использованием метода Regex?
Вот пример:
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();
Я бы хотел, чтобы это было заменено только до первого <\link>
. А затем также сделайте то же самое для остальных этих матчей.
Ответы
Ответ 1
Я считаю, что вам просто нужно добавить ленивый определитель в первом примере. Всякий раз, когда дикая карта "слишком много ест", вам либо нужен ленивый определитель на дикой карте, либо, в более сложном сценарии, смотрите вперед. Добавьте ленивый определитель вверху (.+?
вместо .+
), и вы должны быть хорошими.
Ответ 2
Regex.Match(myString) возвращает первое совпадение, которое оно находит.
Последующие вызовы NextMatch()
для результирующего объекта из Match()
будут продолжать соответствовать следующим вхождениям, если они есть.
Например:
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
}
EDIT: если вы разбираете HTML, я бы серьезно подумал об использовании HTML Agility Pack. Вы спасете много, много головных болей.
Ответ 3
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();
Ответ 4
Используйте группировку в сочетании с RegExOptions.ExplicitCapture
.
Ответ 5
Возможно, немного упрощенное, но если вы получите коллекцию спичек и хотите получить первое вхождение, вы можете посмотреть свойство Match.Index
, чтобы найти самый низкий индекс.
Здесь документация MSDN на нем.
Если это просто проблема с областью, то я согласен с Rich comment - вам нужно использовать не-жадные модификаторы, чтобы остановить ваше выражение от "еды" слишком много.
Ответ 6
попробуйте это
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();