Google风格正则表达式搜索

时间:2009-02-03 04:07:36

标签: php

我使用正则表达已经好几年了,我希望能在我正在做的事情上获得一些帮助。你知道google的搜索功能非常强大,它会把引号中的内容作为一个字面短语,并且在它们前面带有减号的东西不包括在内。

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

显然,我并不是在寻找像谷歌这样复杂的东西我只是想引用我项目的目标。

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

(这是php)

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

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

print_r($matches);

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

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

谢谢!

4 个答案:

答案 0 :(得分:4)

嗯,至少对于这个例子,如果你只想匹配引号内的文本,你需要使用一个捕获组。写得像这样:

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

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

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

将选择所有带引号的字符串,这些字符串有两个由单个空格分隔的小写单词,后跟任何内容。然后$matches[1]将成为第一个单词,$matches[2]将成为第二个单词,$matches[3]将成为“任何内容”。

要查找多个短语,您需要使用preg_match()一次挑选一个短语。您可以传递一个可选的“偏移”参数,它指示字符串中应该开始搜索的位置,并且要找到多个匹配项,您应该将上一次匹配后的位置作为偏移量。有关详细信息,请参阅documentation

您也可以尝试在Google上搜索“正则表达式教程”或类似内容,其中有很多好的。

答案 1 :(得分:1)

很抱歉,但我的php有点生疏,但这段代码可能会按照您的要求执行:

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

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

print_r($matches[1]);

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

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

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

答案 2 :(得分:1)

以下是所有搜索字词的完整答案(字面值,减号,引号,..) WITH替换。 (对于谷歌访问者至少)。

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

  1. 对于您自己或其他开发人员而言,不仅难以工作,而且还会在一个巨大且超级复杂的正则表达式上添加功能
  2. 这种方法甚至可能更快。
  3. 它可能仍需要很多改进,但至少这里是一个完整的解决方案。这里有一些问题,而不是问题中的问题,但它说明了一些选择背后的原因。

    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的答案来到这里!

答案 3 :(得分:0)

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

我最终使用以下内容搜索它们并且它运行良好:

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

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