2009-02-03 63 views
1

自从我使用正则表达式已经有好几年了,我希望能够对我正在开发的某些东西获得一些帮助。您知道Google的搜索功能非常强大,并且将引号内的内容作为文字短语加上,并将前面带有负号的内容作为不包含的内容。谷歌风格正则表达式搜索

示例:“This is literal”-donotfindme site:examplesite.com 本示例将在网站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的,并且不工作完全可以用引号中的多个短语。有人能带领我走向正确的方向吗?

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

谢谢!

回答

4

那么,至少在这个例子中,如果你只想匹配引号内的文本,你需要使用一个捕获组。写这样的:

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

然后$matches将长度为2的数组,其中包含在元件1引号之间的文本(这将仍然包含在元素0相匹配的全文)一般而言,你可以有多组这些括号;它们从1开始的左边开始编号,并且$matches中会有对应的元素,用于每个组匹配的文本。示例:

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

将选择所有带有两个小写单词并由一个空格分隔的引用字符串,后面跟着任何内容。然后$matches[1]将是第一个字,$matches[2]第二个字,和$matches[3]“什么”。

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

你也可以尝试在谷歌搜索“正则表达式教程”或类似的东西,有很多好的东西。

1

很抱歉,但我的PHP是一个有点生疏,但是这个代码可能会做你要求什么:

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

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

print_r($matches[1]); 

$匹配1将包含1日拍摄的子表达式; $匹配或$匹配[0]包含完全匹配的模式。

请参阅preg_match以了解有关子表达式的详细信息。

我不太清楚“引用中的多个短语”是什么意思,但是如果你想匹配平衡的引号,它会更复杂一些并且难以理解。我会拿起参考手册。我强烈推荐Mastering Regular Expressions, by Jeffrey E. F. Friedl。这是理解和使用正则表达式的最佳帮助。这也是一个很好的参考。

0

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

我结束了使用下列人员为他们寻找它完美地工作:

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

此正则表达式与其他不同,因为它正确处理字符串内逃脱引号。

1

这里是完整答案的所有种类的搜索词(文字,减号,引号,..)WITH替换。 (对于谷歌访客至少)。

但是,也许它不应该只用正则表达式来完成。

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