XHP与Regex链接替换



我正在尝试实现一个简单的函数,给定文本输入,当检测到链接时返回xhp_a修改的文本,在段落xhp_p内。

考虑这个类

class Urlifier {
    protected static $reg_exUrl = "/(http|https|ftp|ftps)://[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(/S*)?/";

    public static function convertParagraphWithLink(?string $input):xhp_p{
        if (!$input)
            return <p></p>;
        else
        {
            if (preg_match(self::$reg_exUrl,$input,$url_match)) //match found
            {
                return <p>{preg_replace($reg_exUrl, '<a href="'.$url_match[0].'>'.$url_match[0].'</a>', $input)}<p>;
            }else{//no link inside
                <p>{$input}</p>
            }
        }
}

这里的问题是xhp转义html,链接没有按照预期显示。我想这是因为a没有像预期的那样创建dom层次结构(例如appendChild方法),因此regex替换的所有内容都是字符串。

所以我对这个问题的另一种方法是使用preg_match_callback和一个回调函数,它将创建xhp_a并添加到xhp_p下的层次结构,但这也不起作用。

我错了吗?如果没有,会有任何安全风险/更大的开销,只是寻找和替换加载html在客户端而不是服务器?

感谢您的宝贵时间!

由于XHP维护映射到DOM的对象层次结构,因此简单地替换字符串的部分不会创建任何新对象。要操作XHP对象,应该使用相应的方法,例如appendChild

下面是一个示例,说明如何通过XHP操作实现所需的内容。

class Urlifier {
  public static function convertParagraphWithLink(
    ?string $input,
  ): xhp_p {
    $url_pattern = re"/(http|https|ftp|ftps)://[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(/S*)?/";
    if (HHLibStris_empty($input)) {
      return <p/>;
    }
    $input = $input as nonnull;
    // Extract links
    $link_matches = HHLibRegexevery_match($input, $url_pattern);
    $links = HHLibVecmap($link_matches, $m ==> $m[0]);
    $a_elements = HHLibVecmap($links, $link ==> <a href={$link}>{$link}</a>);
    // Extract all pieces between matches
    $texts = HHLibRegexsplit($input, $url_pattern);
    $p_elements = HHLibVecmap($texts, $text ==> <p>{$text}</p>);
    
    // Merge texts and links
    $pairs = HHLibVeczip($p_elements, $a_elements);
    $elements = HHLibVecflatten($pairs);
    
    // Because there's one more p element than a element, append last p
    $elements[] = HHLibClast($p_elements);
    $result = <p/>;
    $result->appendChild($elements);
    
    return $result;
  }

相关内容

  • 没有找到相关文章

最新更新