什么';这是一种聪明的解析方法;论坛风格”;随机HTML字符串中的标记


What's a smart approach to parsing "forum-style" tags within a string of random HTML?

所以我正在处理存储在数据库中的一些非常棒的HTML字符串,我需要能够解析出"论坛风格"youtube标签之间的字符串,如下例所示。我有一个解决方案,但感觉有点麻烦。我想可能有一种更优雅的方法来处理这个问题。

<?php
    $video_string = '<p><span style="font-size: 12px;"><span style="font-family: verdana,geneva,sans-serif;">[youtube]KbI_7IHAsyw[/youtube]<br /></span></span></p>';
    $matches = array();
    preg_match('/'][_A-Za-z0-9]+'[/', $video_string, $matches);
    $yt_vid_key = substr($matches[0], 1, strlen($matches[0]) - 2 );

我会稍微更改正则表达式:

    '/'[youtube'](.*?)'['/youtube']/is'

添加"youtube"部分以不替换所有bb代码-只替换正确的代码。我还添加了"?"使正则表达式不那么贪婪(例如一篇文章中有多个YT视频。我添加了模式修饰符I和s,以便能够匹配不区分大小写的字符串和多行字符串。

编辑:您可能还想使用preg_replace,这样会减少代码量。

试试这个:

 preg_match('!'[youtube']([_A-Za-z0-9]+?)'[/youtube']!',$subject, $matches);
 $yt_vid_key = $matches[1];

如果希望出现多次,请改用preg_match_all

如果你不期望嵌套标签,这里提供的所有答案都是正确的。如果是这样,那么你必须想出一种方法来正确匹配标签,这在regex中是无法做到的,你必须创建某种方法来处理它。

这里有一些类似伪代码可以帮助你完成

find opening tag to tag match
openTags = 0
closeTags = 0
position = 0
do{
    Move through the string: increase position
    if open tag matches: openTags++
    if close tag matches: closeTags++, positionOfCloseTag = position
}while(openTags > closeTags);
first occurence of close tag after the last close tag you found in do-while loop is the correct matching of the tag.