【问题标题】:Google Style Regular Expression Search谷歌风格正则表达式搜索
【发布时间】:2009-02-03 04:07:35
【问题描述】:

我已经有好几年没有使用正则表达式了,我希望能在我正在做的事情上得到一些帮助。您知道 google 的搜索功能非常强大,会将引号内的内容视为文字短语,而将引号前的内容视为不包括在内。

示例:“这是字面意思”-donotfindme site:examplesite.com 此示例将在 webiste examplesite.com 上不包含单词 donotfindme 的网站中搜索短语“this is literal”。

显然,我不是在寻找像 Google 这样复杂的东西,我只是想参考一下我的项目的发展方向。

无论如何,我首先想从基础知识开始,即引号内的文字短语。在这个网站上另一个问题的帮助下,我能够做到以下几点:

(这是php)

$search = 'hello "this" is regular expressions';
$pattern = '/".*"/';

$regex = preg_match($pattern, $search, $matches);

print_r($matches);

但这会输出“this”而不是所需的this,并且对于引号中的多个短语根本不起作用。有人能引导我走向正确的方向吗?

我不一定需要代码,即使是一个有教程的好地方也可能会完成这项工作。

谢谢!

【问题讨论】:

    标签: php


    【解决方案1】:

    好吧,至少对于这个示例,如果您只想匹配引号内的文本,您将需要使用捕获组。像这样写:

    $pattern = '/"(.*)"/';
    

    然后$matches 将是一个长度为 2 的数组,其中包含元素 1 中引号之间的文本。(它仍将包含与元素 0 匹配的全文) 通常,您可以拥有多个集合这些括号;它们从 1 开始从左开始编号,$matches 中将有一个对应的元素用于每个组匹配的文本。示例:

    $pattern = '/"([a-z]+) ([a-z]+) (.*)"/';
    

    将选择所有带引号的字符串,其中两个小写单词由一个空格分隔,后跟任何内容。那么$matches[1] 将是第一个词,$matches[2] 是第二个词,$matches[3] 是“任何东西”。

    要查找多个短语,您需要使用preg_match() 一次选择一个。您可以传递一个可选的“偏移量”参数,它指示它应该在字符串中的哪个位置开始搜索,并且要找到多个匹配项,您应该在前一个匹配项之后给出位置作为偏移量。详情请见documentation

    您也可以尝试在 Google 上搜索“正则表达式教程”或类似的东西,那里有很多不错的。

    【讨论】:

      【解决方案2】:

      抱歉,我的 php 有点生疏了,但这段代码可能会满足您的要求:

      $search = 'hello "this" is regular expressions';
      $pattern = '/"(.*)"/';
      
      $regex = preg_match($pattern, $search, $matches);
      
      print_r($matches[1]);
      

      $matches1 将包含第一个捕获的子表达式; $matches 或 $matches[0] 包含完全匹配的模式。

      有关子表达式的详细信息,请参阅 PHP 文档中的 preg_match

      我不太清楚您所说的“引号中的多个短语”是什么意思,但是如果您要尝试匹配平衡的引号,则它会涉及更多且难以理解。我会拿起一本参考手册。我强烈推荐Mastering Regular Expressions, by Jeffrey E. F. Friedl。到目前为止,它是理解和使用正则表达式的最佳帮助。这也是一个很好的参考。

      【讨论】:

        【解决方案3】:

        这里是所有搜索字词的完整答案(文字、减号、引号、..)有替换。 (至少对于谷歌访问者)。

        但也许它不应该只使用正则表达式。

        1. 不仅您自己或其他开发人员很难在庞大且超级复杂的正则表达式上工作和添加功能
        2. 使用这种方法甚至可能更快。

        它可能还需要很多改进,但至少这里有一个类中的完整解决方案。这里比问题中提出的要多一些,但它说明了一些选择背后的一些原因。

        class mySearchToSql extends mysqli {
        
            protected function filter($what) {
                if (isset(what) {
                            //echo '<pre>Search string: '.var_export($what,1).'</pre>';//debug
        
                    //Split into different desires
                    preg_match_all('/([^"\-\s]+)|(?:"([^"]+)")|-(\S+)/i',$what,$split);
                            //echo '<pre>'.var_export($split,1).'</pre>';//debug                
        
                    //Surround with SQL
                    array_walk($split[1],'self::sur',array('`Field` LIKE "%','%"'));
                    array_walk($split[2],'self::sur',array('`Desc` REGEXP "[[:<:]]','[[:>:]]"'));
                    array_walk($split[3],'self::sur',array('`Desc` NOT LIKE "%','%"'));
                            //echo '<pre>'.var_export($split,1).'</pre>';//debug
        
                    //Add AND or OR
                    $this   ->where($split[3])                      
                            ->where(array_merge($split[1],$split[2]), true);
                }
            }
        
            protected function sur(&$v,$k,$sur) {
                if (!empty($v))
                    $v=$sur[0].$this->real_escape_string($v).$sur[1];
            }
        
            function where($s,$OR=false) {
                if (empty($s)) return $this;
                if (is_array($s)) {
                    $s=(array_filter($s));
                    if (empty($s)) return $this;
                    if($OR==true)  
                        $this->W[]='('.implode(' OR ',$s).')';
                    else 
                        $this->W[]='('.implode(' AND ',$s).')';
                } else 
                    $this->W[]=$s;
                return $this;
            }
        
            function showSQL() {
                echo $this->W?  'WHERE '.       implode(L.' AND ',$this->W).L:'';
        }
        

        感谢所有 stackoverflow 的答案!

        【讨论】:

          【解决方案4】:

          你很幸运,因为我最近问了一个关于字符串文字的类似问题。你可以在这里找到它:Regex for managing escaped characters for items like string literals

          我最终使用以下方法搜索它们并且效果很好:

          (?<!\\)(?:\\\\)*(\"|')((?:\\.|(?!\1)[^\\])*)\1
          

          此正则表达式与其他正则表达式不同,因为它正确处理字符串中的转义引号。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-21
            • 2015-11-27
            • 2013-04-14
            • 2022-10-14
            • 2013-01-30
            • 1970-01-01
            • 1970-01-01
            • 2020-03-06
            相关资源
            最近更新 更多