2010-02-21 272 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