2013-03-13 179 views
0

我想使用正则表达式的数组来查找和替换PHP中的字符串,但是我得到错误unknown modifier。我知道这似乎是一个流行的问题,但我不明白如何解决它在我的情况。PHP preg_replace“未知修饰符”

这是我原来的正则表达式:

{youtube((?!}).)*} 

我对它运行下面的代码,以逃避任何字符:

$pattern = '/' . preg_quote($pattern) . '/'; 

返回以下内容:

/\{youtube\(\(\?\!\}\)\.\)\*\}/ 

然而,当我通过preg_replace运行此模式时,出现以下错误:

Warning: preg_replace() [function.preg-replace]: Unknown modifier 'y' ... 

任何想法什么需要改变,以及我在这里展示的代码的哪个阶段?

非常感谢

编辑1

按照要求,这里是我使用的代码:

$content = "{youtube}omg{/youtube}"; 
$find = array(); 
$replace = array(); 

$find[] = '{youtube((?!}).)*}'; 
$replace[] = '[embed]http://www.youtube.com/watch?v='; 
$find[] = '{/youtube((?!}).)*}'; 
$replace[] = '[/embed]'; 

foreach ($find as $key => $value) { 
    $find[$key] = '/' . preg_quote($value) . '/'; 
} 

echo preg_replace($find, $replace, $content); 

这里有一个live example

+0

不,你为什么总是使用'preg_quote'。它是用于文字串部分,但你已经有了一个正则表达式模式。 – mario 2013-03-13 12:53:28

+0

马里奥,我认为他们试图隔离原因。它*仍*抛出奇怪错误的事实本身就很有趣。 – Joey 2013-03-13 12:54:10

+0

@mario我使用'preg_quote'来解决早期的问题......但即使没有它,我也会得到同样的错误。 – 2013-03-13 12:55:53

回答

1

只需将您的正则表达式的分隔符更改为在模式中没有使用的东西,在这个例子中我使用了@,它工作正常。

preg_quote只能转义. \ + * ? [^] $ () { } = ! < > | : -,所以当在你的模式中使用非转义字符,但也作为你的正则表达式分隔符,它不会按预期工作。或者像上面那样更改分隔符,或者将其明确地作为preg_quote($str, $delimiter) overload的一部分传递给preg_quote

$content = "{youtube}omg{/youtube}"; 
$find = array(); 
$replace = array(); 

$find[] = '{youtube((?!}).)*}'; 
$replace[] = '[embed]http://www.youtube.com/watch?v='; 
$find[] = '{/youtube((?!}).)*}'; 
$replace[] = '[/embed]'; 

foreach ($find as $key => $value) { 
    $find[$key] = '@' . preg_quote($value) . '@'; 
} 

echo preg_replace($find, $replace, $content); 
+0

嗨,鲁迪,好久不说话......事情怎么样?感谢你(和@mario)指出这个问题,'preg_quote'它没有做替换,但是现在可以删除它了。 – 2013-03-13 13:18:05

+0

选择不在模式中的分隔符并不总是很容易,特别是在运行时计算模式时。更好的方法是使用标准分隔符“/”,并将其作为第二个参数传递给'preg_quote',所以'preg_quote'会将其与其他特殊字符一起引用。查看我的答案代码示例。 – 2013-03-13 13:51:31

+0

@ilmv - 事情很好,你的东西怎么样?应该给我发电子邮件并追上:D – 2013-03-13 14:05:02

0

您应该分隔符传递作为第二个参数为preg_quote这样的:

$find[$key] = '/' . preg_quote ($value, '/') . '/'; 

否则,分隔符将不被引用,因而会产生问题。

0

我可能坐在离电脑不远的医院候诊室里,但是你正在做的事情似乎已经解决了这个问题。

如果我正确地理解这一点,你要替换一些这样的:

{youtube something="maybe"}http://...{/youtube} 

有了:

[embed]http://...[/embed] 

没有?

如果是这样的解决方案是沿着线的东西一样简单的情况:

preg_replace('#{(/?)youtube[^}]*}#', '[\1embed]', $content); 

是标签的开启/关闭的烦躁的保存,并在一些包装的正则表达式的重要考虑因素这与你的目标字符串,在这种情况下,散列并不冲突。

+0

preg_replace_all可能是必要的,以确保您捕获所有的标签,而不仅仅是第一个。 – Steve 2013-03-13 13:28:26

相关问题