2010-11-03 3 views
3

Возьмите следующую строку: «Маркетинг и крикет в Интернете».Поиск всех матчей с регулярным выражением - жадный и не жадный!

Я бы хотел найти все возможные совпадения для "Ma" -any text- "et", используя регулярное выражение. Так ..

  • Рынок
  • Маркетинг и Cricket
  • Маркетинг и сверчок в Интернете

Регулярное выражение Ma.*et возвращается "Маркетинг и крикету в Интернете". Регулярное выражение Ma.*?et возвращает Market. Но я бы хотел, чтобы регулярное выражение возвращало все 3. Возможно ли это?

Спасибо.

+0

Ум, вам действительно нужны регулярные выражения? – Gumbo

+0

LEPL, библиотека синтаксического анализа для Python, имеет регулярные выражения, которые «дают» все возможные совпадения. – delnan

ответ

2

Насколько я знаю: Нет

Но вы могли бы соответствовать нежадным первым, а затем создать новый регулярному_выражению с квантором, чтобы получить второй матч. Как это:

Ma.*?et 
Ma.{3,}?et 

... и так далее ...

0

К сожалению, это невозможно сделать со стандартным регулярным выражением POSIX, которое возвращает один (лучший кандидат в соответствии с правилами регулярных выражений). Вам нужно будет использовать функцию расширения, которая может присутствовать на конкретном языке программирования, в котором вы используете это регулярное выражение, предполагая, что вы используете его в программе, для выполнения этой задачи.

1

Спасибо, ребята, это действительно помогло. Вот что я придумал для PHP:

function preg_match_ubergreedy($regex,$text) { 

    for($i=0;$i<strlen($text);$i++) { 
     $exp = str_replace("*","{".$i."}",$regex); 
     preg_match($exp,$text,$matches); 
     if($matches[0]) { 
      $matched[] = $matches[0]; 
     } 
    } 

    return $matched; 

} 
$text = "Marketing and Cricket on the Internet"; 
$matches = preg_match_ubergreedy("@Ma.*[email protected]",$text); 
0

Для более общего регулярного выражения, другой вариант будет рекурсивно соответствовать жадный регулярное выражение по сравнению с предыдущим матчем, отбрасывая первые и последние символы в свою очередь, для того, чтобы вы соответствуете только подстроке предыдущего совпадения. После сопоставления Marketing and Cricket on the Internet мы тестируем как arketing and Cricket on the Internet, так и Marketing and Cricket on the Interne для подматричек.

Это идет что-то вроде этого в C# ...

public static IEnumerable<Match> SubMatches(Regex r, string input) 
{ 
    var result = new List<Match>(); 

    var matches = r.Matches(input); 
    foreach (Match m in matches) 
    { 
     result.Add(m); 

     if (m.Value.Length > 1) 
     { 
      string prefix = m.Value.Substring(0, m.Value.Length - 1); 
      result.AddRange(SubMatches(r, prefix)); 

      string suffix = m.Value.Substring(1); 
      result.AddRange(SubMatches(r, suffix)); 
     } 

    } 

    return result; 
} 

Эта версия, однако, в конечном итоге возвращаясь в тот же submatch несколько раз, например, он нашел бы Marmoset дважды в Marketing and Marmosets on the Internet, сначала как submatch от Marketing and Marmosets on the Internet, затем в качестве отсылки Marmosets on the Internet.