如何使正则表达式的两个功能兼容?

时间:2015-03-08 15:30:59

标签: jquery regex

下面的代码是将url转换为可点击链接,另一个是为笑脸短代码添加样式。问题是当我使用短代码":/"时,链接显示不正确。这是因为:/也出现在http:// ...请帮我解决。



$(".test1").html(function(i, html) {
  buildhtml = html
  .replace(/(https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?)/ig,"<a href='$1'>$2</a>")
  .replace(/(:\)|:\/|:\D)/ig,"<div class='icon'>$1</div>");
  return buildhtml;
});
&#13;
.icon {color:red}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="test1">
:) :D :/
    
http://link.com
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

作出一般性回答:

你有两个模式有两个替换字符串,但第二个模式匹配第一个模式匹配的部分,你想避免这种情况。

所以方法是使用这种模式:

/(pattern1)|pattern2/g

(...)分隔捕获组1,|是逻辑运算符OR

这可以避免重叠匹配,并且只有一次解析字符串。

String.prototype.replace方法可以将函数替换为:

mystr = mystr.replace(/(pattern1)|pattern2/g, function (m, g1, g2) {
    return (g1) ? 'repla' + g1 + 'cem' + g2 + 'ent1'
                : 'repla' + m + 'cement2';
});

m为完全匹配且gn为捕获组。

return (g1) ? 'repla' + g1 + 'cem' + g2 + 'ent1'
            : 'repla' + m + 'cement2';

是:

的快捷方式
if (g1) { // g1 is only defined when pattern1 succeeds
    return 'repla' + g1 + 'cem' + g2 + 'ent1';
} else {
    return 'repla' + m + 'cement2';
}

完整的工作代码:

模式是:

/(https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?)|(:\)|:\/|:\D)/ig

由于模式1已被parens包围,因此无需将其置于捕获组中。

该模式可以稍微简化为:

/(https?:\/\/([-\w.]+)+(:\d+)?(\/([\w\/.]*(\?\S+)?)?)?)|:[)D\/]/ig

使用您的代码:

$(".test1").html(function(i, html) {
    return html.replace(
        /(https?:\/\/([-\w.]+)+(:\d+)?(\/([\w\/_.]*(\?\S+)?)?)?)|:[)D\/]/ig,
        function (m, g1, g2) {
            return (g1) ? '<a href="' + g1 + '">' + g2 + '</a>'
                        : '<div class="icon">' + m + '</div>';
    });
});