Regex Php将括号和大括号转换为StackOverflow Reddit等链接

时间:2014-04-01 04:06:07

标签: php regex hyperlink

我正在尝试将存储在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,但我认为这对我正在尝试做的事情来说太过分了。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

$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
);