Как указать, чтобы совпадать только с первым появлением? - PullRequest
25 голосов
/ 13 апреля 2010

Как мне указать, чтобы совпадать только с первым появлением регулярного выражения в C # с помощью метода 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>. А затем сделайте то же самое для остальных этих матчей.

Ответы [ 6 ]

32 голосов
/ 13 апреля 2010

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
  }

<час /> РЕДАКТИРОВАТЬ: Если вы анализируете HTML, я бы серьезно подумал об использовании HTML Agility Pack . Вы избавите себя от многих головных болей.

29 голосов
/ 13 апреля 2010

Полагаю, вам просто нужно добавить ленивый классификатор в первом примере. Всякий раз, когда подстановочный знак «съедает слишком много», вам либо нужен ленивый квалификатор на подстановочном знаке, либо, в более сложном сценарии, смотрите вперед. Добавьте ленивый квалификатор вверху (.+? вместо .+), и все будет хорошо.

3 голосов
/ 12 августа 2011
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();
0 голосов
/ 04 июля 2013

попробуйте

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();
0 голосов
/ 13 апреля 2010

Может быть, немного упрощен, но если вы получаете набор совпадений и хотите получить первое вхождение, вы можете посмотреть на свойство Match.Index, чтобы найти самый низкий индекс.

Вот документация MSDN .

Если это просто проблема с областью действия, то я согласен с комментарием Рича - вам нужно использовать не жадные модификаторы, чтобы ваше выражение не слишком "съедало".

0 голосов
/ 13 апреля 2010

Использование группировки в сочетании с RegExOptions.ExplicitCapture.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...