在写谈天体系的时刻,不可避免地要对谈天体系中的音讯做一些剖析
罕见的比方一句话中带有emoji、link等信息的时刻,要把emoji剖析成图片、把link转成能够点击的
(项目中没有做对图片做行内处置惩罚,而是把图片像微信一样作为零丁音讯发送)
我们晓得react的标签都是jsx的,所以在剖析音讯的时刻,就必需在获得音讯内容的时刻,就先把音讯内容分段截取
比方如许一则音讯
本日用饭了吗?[emoji]我还没吃呢[emoji],给你个链接看看吧!http://www.google.com/
emoji要剖析成图片,http://www.google.com/ 要剖析成能够点击的链接,之间的笔墨要剖析成文本
jquery时期,只需要运用正则婚配emoji,替换成图片,用正则婚配链接,替换成a标签即可
但是在react里,这三者对应的是差别的jsx标签。所以必需把文本剖析身分段式的
思绪:
上面这句话,能够剖析成6部份
part1: 本日用饭了吗?
part2: [emoji]
part3: 我还没吃呢
part4: [emoji]
part5: ,给你个链接看看吧!
part6: http://www.google.com/
每部份对应运用差别的jsx标签
第一步,我们先运用正则婚配emoji和链接
离别的正则以下
(婚配链接应该有更优异的正则)
var emojiregex = new RegExp(/\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]/g, 'g'); // 婚配emoji字符
var matchUrlRegex = new RegExp(/(https?:)\/\/([^\/]+)(\/[^\?]*)?(\?[^#]*)?(#.*)?/g,'g'); // 婚配url的正则
var emojiRegArray = text.match(emojiregex); // 婚配了一切的emoji的词
var urlRegArray = text.match(matchUrlRegex);
获得两个数组,离别是婚配到的emoji和婚配到的url
第二步,运用index()要领,猎取每一个emoji、url的位置、长度,并纪录
var indexEmojiArray = []; // 纪录脸色的位置、内容的数组
var indexUrlArray = []; // 纪录链接的位置、内容的数组
var pos1 = -1, pos2 = -1;//头
if(emojiRegArray){
for (let i = 0; i < emojiRegArray.length; i++) {
pos1 = text.indexOf(emojiRegArray[i], pos1 + 1);
indexEmojiArray.push({
type: 1, // type为1示意是脸色
pos: pos1,
length: emojiRegArray[i].length,
res: emojiRegArray[i],
});
}
}
if(urlRegArray){
for (let i = 0; i < urlRegArray.length; i++) {
pos2 = text.indexOf(urlRegArray[i], pos2 + 1);
indexUrlArray.push({
type: 3, // type为1示意是url
pos: pos2,
length: urlRegArray[i].length,
res: urlRegArray[i],
});
}
}
第三步,根据这些元素在音讯中的位置,两个数组兼并成一个数组
// 兼并两个数组
var indexArray = []; // 以上两个数组根据pos递次兼并的数组
if(emojiRegArray && urlRegArray){
let point1 = 0,point2 = 0;
while(point1 < indexEmojiArray.length || point2 < indexUrlArray.length){
if(!indexEmojiArray[point1]){ // emoji加完了
indexArray.push(indexUrlArray[point2]);
point2++;
}else if(!indexUrlArray[point2]){// url加完了
indexArray.push(indexEmojiArray[point1]);
point1++;
}else{ // 两个都没加完
if(indexEmojiArray[point1].pos < indexUrlArray[point2].pos){
indexArray.push(indexEmojiArray[point1]);
point1++;
}else{
indexArray.push(indexUrlArray[point2]);
point2++;
}
}
}
}else if(emojiRegArray && !urlRegArray){ // 有emoji没有url
indexArray = indexEmojiArray;
}else if(!emojiRegArray && urlRegArray){ // 有url没有emoji
indexArray = indexUrlArray;
}
第四步
如今,我们获得了一个indexArray,存储了emoji和url的位置和长度的数组
如今我们要把文本也加进去,而且,emoji替换成图片
// 这里最先把indexArray加工成contentArray
let contentArray = [];
let point = 0; // 纪录当前指针位置
for (let i = 0; i < indexArray.length; i++) {
// 把这一项和上一项之间的内容push成文本
console.log(point);
let textContent = text.substr(point, indexArray[i].pos-point);
console.log(textContent);
contentArray.push({type: 0, content: textContent});
// point += textContent.length;
if(indexArray[i].type === 1){ // 假如这一项是emoji
// contentArray.push({ type: 1, "resources": EMOJI_MAP[indexArray[i].res] || [] });
contentArray.push({ type: 1, resources: indexArray[i].res || [] });
point = indexArray[i].pos + indexArray[i].length;
}else if(indexArray[i].type === 3){ // 假如这一项是url
contentArray.push({ type: 3, url: indexArray[i].res});
point = indexArray[i].pos + indexArray[i].length;
}
}
// 到场末端项。假如indexArray为空,那末末端项就是唯一的文本项
let lastPrevItemIndex = (indexArray[indexArray.length-1] ? indexArray[indexArray.length-1].pos+indexArray[indexArray.length-1].length : 0);
contentArray.push({type: 0, content: text.substr(lastPrevItemIndex, text.length)});
末了获得的contentArray我们return出去。
比较难的部份在第四步,思绪是,我们运用一个指针,对音讯做剖析,一最先指针的位置为0
开首不论怎样都push一个文本对象进入contentArray中
直到碰到emoji或许url位置为止
比方碰到的是emoji,我们把emoji剖析成对象push到contentArray中,然后指针加上emoji的长度
末了加上末端。假如末端不为文本,也增加一个空的文本对象。
终了。
下面附上一切代码
let stringToContentArray = function (text) {
var emojiregex = new RegExp(/\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]/g, 'g');
var matchUrlRegex = new RegExp(/(https?:)\/\/([^\/]+)(\/[^\?]*)?(\?[^#]*)?(#.*)?/g,'g'); // 婚配url的正则
var contentArray = [];
if (!text) { // 没有内容
contentArray.push({ type: 0, "content": '[无内容音讯]' });
return contentArray;
}
var emojiRegArray = text.match(emojiregex); // 婚配了一切的emoji的词
var urlRegArray = text.match(matchUrlRegex);
// console.log(text);
console.log('emojiRegArray:',emojiRegArray);
console.log('urlRegArray:',urlRegArray);
if (emojiRegArray === null && urlRegArray === null) { // 没有emoji脸色, 也没有链接
contentArray.push({ type: 0, "content": text });
return contentArray;
}
var indexEmojiArray = []; // 纪录脸色的位置、内容的数组
var indexUrlArray = []; // 纪录链接的位置、内容的数组
var indexArray = []; // 以上两个数组根据pos递次兼并的数组
var pos1 = -1, pos2 = -1;//头
if(emojiRegArray){
for (let i = 0; i < emojiRegArray.length; i++) {
pos1 = text.indexOf(emojiRegArray[i], pos1 + 1);
indexEmojiArray.push({
type: 1, // type为1示意是脸色
pos: pos1,
length: emojiRegArray[i].length,
res: emojiRegArray[i],
});
}
}
if(urlRegArray){
for (let i = 0; i < urlRegArray.length; i++) {
pos2 = text.indexOf(urlRegArray[i], pos2 + 1);
indexUrlArray.push({
type: 3, // type为1示意是url
pos: pos2,
length: urlRegArray[i].length,
res: urlRegArray[i],
});
}
}
if(emojiRegArray && urlRegArray){
let point1 = 0,point2 = 0;
while(point1 < indexEmojiArray.length || point2 < indexUrlArray.length){
if(!indexEmojiArray[point1]){ // emoji加完了
indexArray.push(indexUrlArray[point2]);
point2++;
}else if(!indexUrlArray[point2]){// url加完了
indexArray.push(indexEmojiArray[point1]);
point1++;
}else{ // 两个都没加完
if(indexEmojiArray[point1].pos < indexUrlArray[point2].pos){
indexArray.push(indexEmojiArray[point1]);
point1++;
}else{
indexArray.push(indexUrlArray[point2]);
point2++;
}
}
}
}else if(emojiRegArray && !urlRegArray){ // 有emoji没有url
indexArray = indexEmojiArray;
}else if(!emojiRegArray && urlRegArray){ // 有url没有emoji
indexArray = indexUrlArray;
}
console.log("indexArray: ", indexArray);
// 这里最先把indexArray加工成contentArray
let point = 0; // 纪录当前指针位置
for (let i = 0; i < indexArray.length; i++) {
// 把这一项和上一项之间的内容push成文本
console.log(point);
let textContent = text.substr(point, indexArray[i].pos-point);
console.log(textContent);
contentArray.push({type: 0, content: textContent});
// point += textContent.length;
if(indexArray[i].type === 1){ // 假如这一项是emoji
// contentArray.push({ type: 1, "resources": EMOJI_MAP[indexArray[i].res] || [] });
contentArray.push({ type: 1, resources: indexArray[i].res || [] });
point = indexArray[i].pos + indexArray[i].length;
}else if(indexArray[i].type === 3){ // 假如这一项是url
contentArray.push({ type: 3, url: indexArray[i].res});
point = indexArray[i].pos + indexArray[i].length;
}
}
// 到场末端项。假如indexArray为空,那末末端项就是唯一的文本项
let lastPrevItemIndex = (indexArray[indexArray.length-1] ? indexArray[indexArray.length-1].pos+indexArray[indexArray.length-1].length : 0);
contentArray.push({type: 0, content: text.substr(lastPrevItemIndex, text.length)});
return contentArray;
}