【问题标题】:Finding all matches with a regular expression - greedy and non greedy!使用正则表达式查找所有匹配项 - 贪婪和非贪婪!
【发布时间】:2011-05-04 17:55:41
【问题描述】:

采用以下字符串:“互联网上的营销和板球”。

我想使用正则表达式查找“​​Ma”-any text-“et”的所有可能匹配项。所以..

  • 市场
  • 营销和板球
  • 互联网营销和板球

正则表达式Ma.*et 返回“互联网营销和板球”。正则表达式 Ma.*?et 返回市场。但我想要一个返回所有 3 的正则表达式。这可能吗?

谢谢。

【问题讨论】:

  • 嗯,你真的需要正则表达式吗?
  • LEPL,一个 Python 的解析库,有 yield 所有可能匹配的正则表达式。

标签: regex regex-greedy


【解决方案1】:

据我所知:没有。

但是您可以先匹配非贪婪,然后生成一个带有量词的新正则表达式以获得第二个匹配。 像这样:

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

...等等...

【讨论】:

    【解决方案2】:

    谢谢大家,这真的很有帮助。以下是我为 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.*?et@is",$text);
    

    【讨论】:

      【解决方案3】:

      遗憾的是,标准 POSIX 正则表达式无法做到这一点,它返回单个(最佳候选,每个正则表达式规则)匹配。假设您在程序中使用它,您将需要利用可能存在于您使用此正则表达式的特定编程语言中的扩展功能来完成此任务。

      【讨论】:

        【解决方案4】:

        对于更通用的正则表达式,另一种选择是递归匹配贪婪正则表达式与前一个匹配项,依次丢弃第一个和最后一个字符以确保您只匹配前一个匹配项的子字符串。匹配Marketing and Cricket on the Internet 后,我们同时测试arketing and Cricket on the InternetMarketing 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;
        }
        

        然而,这个版本可能会多次返回相同的子匹配,例如它会在Marketing and Marmosets on the Internet 中找到两次Marmoset,首先是Marketing and Marmosets on the Internet 的子匹配,然后是Marmosets on the Internet 的子匹配。

        【讨论】:

          猜你喜欢
          • 2011-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多