PHP preg_replace - 不匹配锚链接
PHP preg_replace - do not match anchor links
我的 Wordpress 主题中有一个自定义功能,用于查找 YouTube 网址并自动将它们转换为嵌入式 iframe。这很好用,但有一个小问题。目前,该功能还取代了链接到文本的 YouTube 链接。因此,如果我有一个指向 YouTube 的锚标记,它会将 iframe 代码扔到锚中并导致 HTML 问题。
因此,如果我有一个 Wordpress post 并且我在 post 中有以下内容,我希望将其转换为 iframe:
https://www.youtube.com/watch?v=HDDLTwS4zgs
但是如果我有链接到 YouTube 的文本,我不希望它被转换:
<a href="https://www.youtube.com/watch?v=HDDLTwS4zgs">Check out Linus' latest video</a>
这是我的 PHP 函数:
function convertYoutube($string) {
return preg_replace(
"/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
"<div class=\"embed-responsive embed-responsive-16by9 scroll-in\"><iframe width=\"560\" height=\"315\" src=\"//www.youtube.com/embed/\" frameborder=\"0\" allowfullscreen></iframe></div>",
$string
);
}
add_filter('the_content', 'convertYoutube');
可以通过添加 <a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|
替代方案来修复模式:
'~<a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|\s*[a-zA-Z/:.]*youtu(be\.com/watch\?v=|\.be/)([\w-]+)([\w/*?&;%=.-]*)~'
参见regex demo。
另请注意,如果您使用不同的正则表达式分隔符,则 /
不需要转义。字符 class、[...]
之外的 .
必须转义以匹配文字点。如果不使用 u
修饰符,\w
等于 [A-Za-z0-9_]
。字符 class、[...]
内的 -
不必在 class 的 start/end 处(以及在范围或 shorthand 字符 class).
更新模式详细信息
<a\b
- 匹配整个字符串 <a
- [^>]*
- >
以外的 0+ 个字符
- >
- >
符号
- [^<]*
- <
以外的 0+ 个字符
- </a>
- 文字子串
- (*SKIP)(*FAIL)
- PCRE 动词跳过匹配并在上一个省略的匹配结束时继续搜索新匹配。
我的 Wordpress 主题中有一个自定义功能,用于查找 YouTube 网址并自动将它们转换为嵌入式 iframe。这很好用,但有一个小问题。目前,该功能还取代了链接到文本的 YouTube 链接。因此,如果我有一个指向 YouTube 的锚标记,它会将 iframe 代码扔到锚中并导致 HTML 问题。
因此,如果我有一个 Wordpress post 并且我在 post 中有以下内容,我希望将其转换为 iframe:
https://www.youtube.com/watch?v=HDDLTwS4zgs
但是如果我有链接到 YouTube 的文本,我不希望它被转换:
<a href="https://www.youtube.com/watch?v=HDDLTwS4zgs">Check out Linus' latest video</a>
这是我的 PHP 函数:
function convertYoutube($string) {
return preg_replace(
"/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
"<div class=\"embed-responsive embed-responsive-16by9 scroll-in\"><iframe width=\"560\" height=\"315\" src=\"//www.youtube.com/embed/\" frameborder=\"0\" allowfullscreen></iframe></div>",
$string
);
}
add_filter('the_content', 'convertYoutube');
可以通过添加 <a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|
替代方案来修复模式:
'~<a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|\s*[a-zA-Z/:.]*youtu(be\.com/watch\?v=|\.be/)([\w-]+)([\w/*?&;%=.-]*)~'
参见regex demo。
另请注意,如果您使用不同的正则表达式分隔符,则 /
不需要转义。字符 class、[...]
之外的 .
必须转义以匹配文字点。如果不使用 u
修饰符,\w
等于 [A-Za-z0-9_]
。字符 class、[...]
内的 -
不必在 class 的 start/end 处(以及在范围或 shorthand 字符 class).
更新模式详细信息
<a\b
- 匹配整个字符串 <a
- [^>]*
- >
以外的 0+ 个字符
- >
- >
符号
- [^<]*
- <
以外的 0+ 个字符
- </a>
- 文字子串
- (*SKIP)(*FAIL)
- PCRE 动词跳过匹配并在上一个省略的匹配结束时继续搜索新匹配。