2010-02-21 271 views
7

有没有办法将通配符放入字符串?我问的原因是因为目前我有一个函数来搜索两个子串之间的子串(即在“我的狗有跳蚤”的句子中抓住“我的”和“有跳蚤”之间的内容,导致“狗” )。PHP搜索字符串(带通配符)

function get_string_between($string, $start, $end){ 
    $string = " ".$string; 
    $ini = strpos($string,$start); 
    if ($ini == 0) return ""; 
    $ini += strlen($start); 
    $len = strpos($string,$end,$ini) - $ini; 
    return substr($string,$ini,$len); 
} 

我想要做的就是让它用字符串中的通配符进行搜索。所以说我在“我的狗有跳蚤”的句子中搜索“%WILDCARD%”和“跳蚤” - 它仍然会输出“狗”。

我不知道我是否解释得太好,但希望有人能理解我:P。非常感谢您的阅读!

+1

,如果你想通配符,你可以使用正则表达式来代替。 – ghostdog74 2010-02-21 08:57:02

+0

非常感谢你们,真的! – Baehr 2010-02-21 09:07:45

回答

8

这是少数情况下正则表达式实际上有用的情况之一。 :)

if (preg_match('/my (\w+) has/', $str, $matches)) { 
    echo $matches[1]; 
} 

请参阅preg_match的文档。

+10

这只是无知,正则表达式是优秀的工具。 – raveren 2010-10-26 17:37:16

+0

@Raveren:正则表达式是傻瓜手中可怕的工具。很多人在不了解它们的限制的情况下使用它们,存在什么样的引擎等等。 – Christian 2011-02-18 22:43:55

+15

*正则表达式是傻瓜手中可怕的工具。*因此字面上每一个其他工具都存在。 – raveren 2011-02-19 13:09:19

2

使用正则表达式。

$string = "My dog has fleas"; 
if (preg_match("/\S+ (\S+) has fleas/", $string, $matches)) 
    echo ($matches[1]); 
else 
    echo ("Not found"); 

\S指任何非空格字符,+指一个或多个以前的事情,所以\S+意味着匹配一个或多个非空格字符。 (…)表示捕获submatch的内容并放入$matches数组中。

0

如果你坚持使用通配符(并且是的,PREG好得多),你可以使用功能 fnmatch,它只适用于* NIX。

干杯

3

我同意,正则表达式比通配符更加灵活,但有时你想要的是一个简单的方法来定义模式。对于人们在寻找一个便携式解决方案(不* NIX只)这里是我实现的功能:

function wild_compare($wild, $string) { 
    $wild_i = 0; 
    $string_i = 0; 

    $wild_len = strlen($wild); 
    $string_len = strlen($string); 

    while ($string_i < $string_len && $wild[$wild_i] != '*') { 
     if (($wild[$wild_i] != $string[$string_i]) && ($wild[$wild_i] != '?')) { 
      return 0; 
     } 
     $wild_i++; 
     $string_i++; 
    } 

    $mp = 0; 
    $cp = 0; 

    while ($string_i < $string_len) { 
     if ($wild[$wild_i] == '*') { 
      if (++$wild_i == $wild_len) { 
       return 1; 
      } 
      $mp = $wild_i; 
      $cp = $string_i + 1; 
     } 
     else 
     if (($wild[$wild_i] == $string[$string_i]) || ($wild[$wild_i] == '?')) { 
      $wild_i++; 
      $string_i++; 
     } 
     else { 
      $wild_i = $mp; 
      $string_i = $cp++; 
     } 
    } 

    while ($wild[$wild_i] == '*') { 
     $wild_i++; 
    } 

    return $wild_i == $wild_len ? 1 : 0; 
} 

自然PHP实现比的fnmatch慢(),但它会在任何平台上运行。

它可用于这样的:

if (wild_compare('regex are * useful', 'regex are always useful') == 1) { 
    echo "I'm glad we agree on this"; 
} 
+0

好!我们有要求允许我们的员工输入正则表达式规则来匹配某些数据。由于他们不理解正则表达式,这是完美的解决方案! – Luc 2013-08-20 01:32:43

1

通配符模式可以转换为正则表达式模式这样

function wildcard_match($pattern, $subject) { 
    $pattern = strtr($pattern, array(
    '*' => '.*?', // 0 or more (lazy) - asterisk (*) 
    '?' => '.', // 1 character - question mark (?) 
)); 
    return preg_match("/$pattern/", $subject); 
} 

如果字符串内容的特殊字符,例如?\ + *^$ | {} /'#,他们应该是\转义

不进行测试:

function wildcard_match($pattern, $subject) { 
    // quotemeta function has most similar behavior, 
    // it escapes \.+*?^$[](), but doesn't escape |{}/'# 
    // we don't include * and ? 
    $special_chars = "\.+^$[]()|{}/'#"; 
    $special_chars = str_split($special_chars); 
    $escape = array(); 
    foreach ($special_chars as $char) $escape[$char] = "\\$char"; 
    $pattern = strtr($pattern, $escape); 
    $pattern = strtr($pattern, array(
    '*' => '.*?', // 0 or more (lazy) - asterisk (*) 
    '?' => '.', // 1 character - question mark (?) 
)); 
    return preg_match("/$pattern/", $subject); 
} 
+0

$ pattern应该可能有一个preg_quote arround – velop 2014-05-27 13:14:16