有没有办法在字符串中放一个通配符?我问的原因是因为目前我有一个函数来搜索两个子串之间的子串(即在“我的狗有跳蚤”这句话中抓住“我的”和“有跳蚤”之间的内容,导致“狗” )。
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。非常感谢您的阅读!
答案 0 :(得分:9)
这是正则表达式实际上有用的少数情况之一。 :)
if (preg_match('/my (\w+) has/', $str, $matches)) {
echo $matches[1];
}
请参阅preg_match的文档。
答案 1 :(得分: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";
}
答案 2 :(得分:3)
通配符模式可以像这样转换为正则表达式模式
function wildcard_match($pattern, $subject) {
$pattern = strtr($pattern, array(
'*' => '.*?', // 0 or more (lazy) - asterisk (*)
'?' => '.', // 1 character - question mark (?)
));
return preg_match("/$pattern/", $subject);
}
如果字符串包含特殊字符,例如\。+ *?^ $ | {} /'#,它们应该是\ -escaped
未经测试:
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);
}
答案 3 :(得分:2)
使用正则表达式。
$string = "My dog has fleas";
if (preg_match("/\S+ (\S+) has fleas/", $string, $matches))
echo ($matches[1]);
else
echo ("Not found");
\S
表示任何非空格字符,+
表示前一个或多个字符,因此\S+
表示匹配一个或多个非空格字符。 (…)
表示捕获子匹配的内容并放入$matches
数组。
答案 4 :(得分:0)
如果你坚持使用通配符(是的,PREG要好得多)你可以使用函数 fnmatch仅适用于* NIX。
干杯