javascript-正则表达式匹配出URL地址,批量添加a标签

一开始接到这个需求觉得简单,结果越搞越复杂,反复了很多次,没有特别好的解决方案

最近接到一个需求,客服输入框需要将发送出去的消息中含有url地址匹配出来添加上a标签,但是由于输入框是富文本,所以输入框内有可能有各种标签,像a、p标签等。

最开始我在网上找到一个正则表达式,但是会匹配邮箱、数字(类似www123@fenxin.com、123.123、hae.123),后来经过好几轮正则替换。

A同事找的:

 (((ht|f)tps?):\/\/)?[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?(?<!@[\w\-]+(\.[\w\-]+)*)

这个不匹配邮箱,但是客户有数字123.123、密码hahh.123这种也会匹配,不确定可能得情况,进行一一排除不太好。

B同事自己写的:

^((https|http)://)?[A-Za-z0-9+&#/%?=~_|!:,.;]+\.(com|net|cn|vip|org|edu|info|gov|top|xyz|html)$

这个只能完全匹配单个url的情况,多个url不匹配、邮箱、数字、ip等不匹配,本想着就这样限制死算了,结果最近又发现富文本消息默认有p标签等,我是将p标签替换掉之后使用正则匹配的,这样本来换行的消息就不换行了,于是又要改正则了。

最终方案:

C同事写的正则(无法排除邮箱,需要加一些限制):
具体逻辑:
首先判断消息中是否有a标签,如果有则原样返回,不做处理

let aExp = /<a.+?href=\"(.+?)\".*>(.+)<\/a>/gi
let textStr = text.replace(/<p>/g,'').replace(/<\/p>/g,'').replace(/&gt;/g,'>').replace(/&lt;/g,'<')
if(aExp.test(textStr)){
   return text
}

如果没有,则判断是否含有邮箱,如果有将邮箱用特殊字符“_$1_temp”替换,然后在进行url正则匹配;最后利用匹配出来的邮箱数组,批量将特殊字符再替换回来。

let exp = /(https?:\/\/)?((((25[0-5])|(2[0-4][0-9])|(1\d{2})|(\d{2})|([1-9]))(\.((25[0-5])|(2[0-4][0-9])|(1\d{2})|(\d{2})|(\d))){2}\.((25[0-5])|(2[0-4][0-9])|(1\d{2})|(\d{2})|(\d)))|((([A-Za-z0-9][A-Za-z0-9\-]{0,19})\.)?([A-Za-z0-9][A-Za-z0-9\-]{0,19})\.(com|net|cn|vip|org|edu|info|gov|top|xyz|icu|com.cn)))((:\d{2,5})?)(((\/([^<\s]+)?)+(\.[^<\s])?)?)((\?(\S+\=\S+)(&(\S+\=\S+))*)?)/gi
let emailExp = /(?:[a-z0-9+!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/gi
let emailArr = text.match(emailExp)
let a2 = text.replace(emailExp, function(){
	return '_$1_temp'
}).replace(exp, function(a){
	if(!a.indexOf('http')){
		return '<a href="'+a+'" target="_blank">'+a+'</a>'
	} else {
		return '<a href="http://'+a+'" target="_blank">http://'+a+'</a>'
	}
})
if(emailArr&&emailArr.length>0){
	let result = emailArr.map((item, i) => {
		a2 = a2.replace('_$1_temp',item)
		return a2
	})
	return result[result.length - 1]
} else {
	return a2
}

在这里插入图片描述
在这里插入图片描述
目前这个方法不是太好,如果消息中存在a标签,就没有做其他url替换;正常的逻辑是a标签的url不替换,其他正常的url替换,目前这方式还不知道有没有其他问题。

不知道有没有大佬有完美的解决方案,可以满足匹配富文本消息中所有url批量替换加上a标签;同时不匹配:带有a标签的url、邮箱、123.23、haha.123、123.123.123等不是真正url的字符串,富文本消息中的标签正常返回,不影响换行等样式。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个大土豆的日常

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值