我不是一个程序员,但是我需要在PHP中编写一个简单的 preg_replace 语句来帮助我使用WordPress插件。基本上,我需要一些代码来搜索字符串,拉出视频ID,并返回插入视频ID的嵌入代码。
换句话说,我正在寻找这个:
[youtube=http://www.youtube.com/watch?v=VIDEO_ID_HERE&hl=en&fs=1]
并希望用此替换它(保持视频ID相同):
param name="movie" value="http://www.youtube.com/v/VIDEO_ID_HERE&hl=en&fs=1&rel=0
如果可能的话,如果你能解释一下你如何在搜索模式中使用各种斜线,插入符号和Kleene星,即将它从grep翻译成英语,我将永远感激,这样我就可以学习。 : - )
谢谢!
麦克
答案 0 :(得分:6)
小心!如果这是一个具有用户输入的BBCode风格的系统,那么这两个其他解决方案将使您容易受到XSS攻击。
你有几种方法可以保护自己免受这种伤害。让正则表达式明确禁止可能让你遇到麻烦的字符(或者只允许那些对youtube视频id有效的字符),或者实际上清理输入并使用preg_match,我将在下面说明RoBorg的正则表达式。
<?php
$input = "[youtube=http://www.youtube.com/watch?v=VIDEO_ID_HERE&hl=en&fs=1]";
if ( preg_match('/\[youtube=.*?v=(.*?)&.*?\]/i', $input, $matches ) )
{
$sanitizedVideoId = urlencode( strip_tags( $matches[1] ) );
echo 'param name="movie" value="http://www.youtube.com/v/' . $sanitizedVideoId . '&hl=en&fs=1&rel=0';
} else {
// Not valid input
}
以下是此类攻击行动的一个示例
<?php
$input = "[youtube=http://www.youtube.com/watch?v=\"><script src=\"http://example.com/xss.js\"></script>&hl=en&fs=1]";
// Is vulnerable to XSS
echo preg_replace('/\[youtube=.*?v=(.*?)&.*?\]/i', 'param name="movie" value="http://www.youtube.com/v/$1&hl=en&fs=1&rel=0', $input );
echo "\n";
// Prevents XSS
if ( preg_match('/\[youtube=.*?v=(.*?)&.*?\]/i', $input, $matches ) )
{
$sanitizedVideoId = urlencode( strip_tags( $matches[1] ) );
echo 'param name="movie" value="http://www.youtube.com/v/' . $sanitizedVideoId . '&hl=en&fs=1&rel=0';
} else {
// Not valid input
}
答案 1 :(得分:2)
$str = preg_replace('/\[youtube=.*?v=([a-z0-9_-]+?)&.*?\]/i', 'param name="movie" value="http://www.youtube.com/v/$1&hl=en&fs=1&rel=0', $str);
/ - Start of RE
\[ - A literal [ ([ is a special character so it needs escaping)
youtube= - Make sure we've got the right tag
.*? - Any old rubbish, but don't be greedy; stop when we reach...
v= - ...this text
([a-z0-9_-]+?) - Take some more text (just z-a 0-9 _ and -), and don't be greedy. Capture it using (). This will get put in $1
&.*?\] - the junk up to the ending ]
/i - end the RE and make it case-insensitive for the hell of it
答案 2 :(得分:1)
如果可能的话,我会在这种情况下避免正则表达式,因为:谁保证第一个url中的查询字符串将始终采用该格式?
我使用parse_url($originalURL, PHP-URL-QUERY);
然后遍历返回的数组,为查询字符串的v部分找到正确的'name = value'对:
类似的东西:
$originalURL = 'http://www.youtube.com/watch?v=VIDEO_ID_HERE&hl=en&fs=1';
foreach( parse_url( $originalURL, PHP_URL_QUERY) as $keyvalue )
{
if ( strlen( $keyvalue ) > 2 && substr( $keyvalue, 0, 2 ) == 'v=' )
{
$videoId = substr( $keyvalue, 2 );
break;
}
}
$newURL = sprintf( 'http://www.youtube.com/v/%s/whatever/else', url_encode( $videoId ) );
P.S。写在SO文本框中,未经测试。
答案 3 :(得分:0)
$embedString = 'youtube=http://www.youtube.com/watch?v=VIDEO_ID_HERE&hl=en&fs=1';
preg_match('/v=([^&]*)/',$embedstring,$matches);
echo 'param name="movie" value="http://www.youtube.com/v/'.$matches[1].'&hl=en&fs=1&rel=0';
试试。
正则表达式/v=([^&]*)/
以这种方式工作:
v=
$matches
[^&]
告诉它匹配任何字符除了&符号('&amp;')*
告诉我们我们希望匹配中从0到任意数量的任何字符答案 4 :(得分:0)
警告。如果未立即找到.*?
之后的文本,则正则表达式引擎将继续搜索整行,可能会跳转到下一个[youtube...]
标记。通常最好使用[^\]]*?
来限制括号内的搜索。
基于RoBorgs回答:
$str = preg_replace('/\[youtube=[^\]]*?v=([^\]]*?)&[^\]]*?\]/i', ...)
[^\]]
将匹配除']'
以外的任何字符。