Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP提取类似HTML的标记_Php_Dom_String - Fatal编程技术网

使用PHP提取类似HTML的标记

使用PHP提取类似HTML的标记,php,dom,string,Php,Dom,String,我试图从给定字符串中提取最外层的特殊HTML标记。下面是一个示例字符串: sample string with <::Class id="some id\" and more">text with possible other tags inside<::/Class> some more text 带有的示例字符串不是可扩展的解决方案,但它可以工作 $startPos = strpos($string, '<::Class'); $endPos = strrpo

我试图从给定字符串中提取最外层的特殊HTML标记。下面是一个示例字符串:

sample string with <::Class id="some id\" and more">text with possible other tags inside<::/Class> some more text
带有的示例字符串不是可扩展的解决方案,但它可以工作

$startPos = strpos($string, '<::Class');
$endPos = strrpos($string, '<::/Class>');

$startPos=strpos($string,您在这里谈论的是制作模板。用于解析模板的Regex非常慢。相反,您的模板读取/处理引擎应该进行字符串解析。这不是非常简单,但也不是非常难。不过,我的建议是使用另一个模板库,而不是重新发明轮子


有一个开源的模板引擎,您可以利用它或从中学习。或者,使用类似的东西。如果性能是一项重要任务,请查看。

strpos+strrpos
(哎哟…)


基本上这就是我的想法。类似于ajreal的解决方案只是不够干净;]甚至不确定它是否能完美工作,初始测试是成功的

protected function findFirstControl()
{
    $pos = strpos($this->mSource, '<::');

    if ($pos === false)
        return false;

    // get the control name
    $endOfName = false;
    $controlName = '';
    $len = strlen($this->mSource);
    $i = $pos + 3;

    while (!$endOfName && $i < $len)
    {
        $char = $this->mSource[$i];

        if (($char >= 'a' && $char <= 'z') || ($char >= 'A' && $char <= 'Z'))
            $controlName .= $char;
        else
            $endOfName = true;

        $i++;
    }

    if ($controlName == '')
        return false;

    $posOfEnd = strpos($this->mSource, '<::/' . $controlName, $i);
    $posOfStart = strpos($this->mSource, '<::' . $controlName, $i);

    if ($posOfEnd === false)
        return false;

    if ($posOfStart > $pos)
    {
        while ($posOfStart > $pos && $posOfEnd !== false && $posOfStart < $posOfEnd)
        {
            $i = $posOfStart + 1;
            $n = $posOfEnd + 1;
            $posOfStart = strpos($this->mSource, '<::' . $controlName, $i);
            $posOfEnd = strpos($this->mSource, '<::/' . $controlName, $n);
        }
    }

    if ($posOfEnd !== false)
    {
        $ln = $posOfEnd - $pos + strlen($controlName) + 5;
        return array($pos, $ln, $controlName, substr($this->mSource, $pos, $ln));
    }
    else
        return false;
}
受保护函数findFirstControl()
{

$pos=strpos($this->mSource,'它不起作用,因为可能有嵌套的标记。我还需要匹配@Marius:为什么不将其更改为XML?另外,如果仔细观察,您会发现第二个方法是,而不是
strpos
。该函数在字符串中找到最后一个匹配项。同意“只使用常规XML”,然后解析它?不管它是否是strrpos,因为可能会有两个标签一个接一个。strrpos会返回第二个标签的结尾。我尝试过HTML,但使用DomDocument,我无法仅将标签作为对象获取,而不知道它在字符串中的位置。这正是我的答案试图说明的缺陷即使你想让它工作,效率也会非常低。发明轮子正是这里的目的。我不会把时间浪费在一些商业项目上,但我正在努力学习一些东西,即使这意味着重新发明轮子。这是我自己做事的方式。总是。我更想知道事情是如何工作的而不是盲目地使用某些东西。如果它是开源的,就不是盲目的:)@马吕斯:是的,你可以自由地查看代码并了解它是如何完成的。而且列出的模板引擎中没有一个是商业产品。我想我必须四处看看,并尝试从代码中了解一些东西;]Blitz是用C编写的扩展。我以前也看到过这样做-速度非常快。PHPBB引擎历史上是v从“html注释”开始,设计师通常理解样式在DreamWeaver等应用中发挥了很大的作用,因此有一个优势。OP只是讨论了“最外面的”标记。创建一个非常大的模板的整个映射可能会变得很大。只要所有额外的内存不是问题,这将是一种可行的方法。如果内存是问题,您也可以使用i创建一个标记=>位置的映射n字符串。感谢您为此花费时间。事实上,我已经解决了这个问题。查看您的代码,我可以看到我的方法可能完全相同,只是它没有生成映射,只是替换了第一次出现的内容。好吧,不确定它会有多大用处,因为您已经发布了一个更简洁的解决方案;]
array (
  0 => 'sample string with ',
  1 => '<::Class id="some id" and more">',
  2 => 'text with possible ',
  3 => '<::Strong>',
  4 => 'other',
  5 => '<::/Strong>',
  6 => ' tags inside',
  7 => '<::/Class> some more text',
)
protected function findFirstControl()
{
    $pos = strpos($this->mSource, '<::');

    if ($pos === false)
        return false;

    // get the control name
    $endOfName = false;
    $controlName = '';
    $len = strlen($this->mSource);
    $i = $pos + 3;

    while (!$endOfName && $i < $len)
    {
        $char = $this->mSource[$i];

        if (($char >= 'a' && $char <= 'z') || ($char >= 'A' && $char <= 'Z'))
            $controlName .= $char;
        else
            $endOfName = true;

        $i++;
    }

    if ($controlName == '')
        return false;

    $posOfEnd = strpos($this->mSource, '<::/' . $controlName, $i);
    $posOfStart = strpos($this->mSource, '<::' . $controlName, $i);

    if ($posOfEnd === false)
        return false;

    if ($posOfStart > $pos)
    {
        while ($posOfStart > $pos && $posOfEnd !== false && $posOfStart < $posOfEnd)
        {
            $i = $posOfStart + 1;
            $n = $posOfEnd + 1;
            $posOfStart = strpos($this->mSource, '<::' . $controlName, $i);
            $posOfEnd = strpos($this->mSource, '<::/' . $controlName, $n);
        }
    }

    if ($posOfEnd !== false)
    {
        $ln = $posOfEnd - $pos + strlen($controlName) + 5;
        return array($pos, $ln, $controlName, substr($this->mSource, $pos, $ln));
    }
    else
        return false;
}