【问题标题】:Regex Php convert brackets and braces to links like StackOverflow RedditRegex Php 将括号和大括号转换为 StackOverflow Reddit 等链接
【发布时间】:2014-05-11 16:17:27
【问题描述】:

我正在尝试将用户在存储在 mysql 数据库中的文本框中发布的一些标记解析为链接,类似于 Reddit 和 StackOverflow 的使用方式:

 [foo](http://foo.com) = <a href="http://foo.com">foo</a>

到目前为止,我想出了这个:

 if (stristr($text, '[') == TRUE && stristr($text, '](') == TRUE && 
     stristr($text, ')') == TRUE && strpos($text, '[') == 0) {
      $text = substr($text, 0, strpos($text, ']'));
      $href_start = strpos($text, '(');
      $href = substr($title, $href_start, strpos($text, ')'));
      $text_array = array('[', ']'); $href_array = array('(', ')');
      $href = str_replace($href_array, '', $href);
      $text_string = str_replace($text_array, '', $text_string);
      $text = '<a href="' . $href . '">' . $text_string . '</a>';
 }

这有效,但仅当评论以链接开头时,而不是当链接出现在文本中间时。我还需要从括号中的字符串中获取一定数量的文本,用于需要显示的文本标题,所以有时我会这样写最后一个字符串:

$title = '<a href="' . $href . '">' . substr($text, 0, 80) . '</a>';

如果有人能告诉我如何在执行此字符串操作时获取可变数量的文本,那么加分。我知道 PHP Markdown,但我认为这对于我正在尝试做的事情来说太过分了。

【问题讨论】:

    标签: php regex hyperlink


    【解决方案1】:
    $string = <<<EOS
    some text [foo](http://foo.com) and
    more text [bar](http://bar.com) and then
    a [really looooooooooooooooooooooooooooooooooooooooooooooo00000000000000000ooong description](http://foobar.com)
    EOS;
    
    
    $string = preg_replace_callback(
      '~\[([^\]]+)\]\(([^)]+)\)~',
      function ($m) {
        return '<a href="'.$m[2].'">'.substr($m[1],0,80).'</a>';
      },
      $string
    );
    
    echo $string;
    

    输出:

    some text <a href="http://foo.com">foo</a> and
    more text <a href="http://bar.com">bar</a> and then
    a <a href="http://foobar.com">really looooooooooooooooooooooooooooooooooooooooooooooo00000000000000000ooong de</a>
    

    编辑:

    我想您不需要为此使用preg_replace_callback - 可以改用preg_replace,但我更喜欢前者,因为正则表达式更简洁,您可以使用对建立链接有更多的控制。但这里是preg_replace 版本:

    $string = preg_replace(
      '~\[([^\]]{1,80})[^\]]*\]\(([^)]+)\)~',
      '<a href="$2">$1</a>',
      $string
    );
    

    【讨论】:

      【解决方案2】:

      使用这个正则表达式:

      \[(.{1,80}).*?\]\((.+?)\)
      

      并将其替换为:

      <a href="$2">$1</a>
      

      您可以使用$1 作为标题,将其拆分为' ' 或保持原样。

      代码:

      <?php
      $string = '[foo](http://nettpals.in)';
      $pattern = '/\[(.{1,80}).*?\]\((.+?)\)/';
      $replacement = '<a href="$2">$1</a>';
      echo preg_replace($pattern, $replacement, $string);
      ?>
      

      演示:http://ideone.com/xiAT6w

      【讨论】:

      • @AmitJoki 它可以工作,但我很困惑你如何实现使用 preg_relace 用 $1 代替长度的最后一部分: $text = preg_replace('#[(.*)](( .*))#', '$1', $text);
      • @user3423909,现在看看我的回答
      • @AmitJoki 这样做的一个问题是,这并没有说明他想要将链接文本剪切到最多 80 个字符...
      • @AmitJoki 是的,他^^说的。我怎样才能最多输出 80 个字符或任意数量的字符?不知道也没关系。
      • @AmitJoki 不完全......尝试使用超过 80 个字符的字符串!
      猜你喜欢
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      • 2017-09-29
      • 1970-01-01
      • 2012-11-09
      相关资源
      最近更新 更多