正则表达式是功能强大的利器,无关乎语言,无关乎场景。
故事的背景
但凡是故事,都会有背景,这段故事的背景大致如下:服务端通过API返回了一组JSON数据,其中包含一个参数是通过富文本编辑器编辑的内容(服务端应邀,把html标签做了处理,只保留链接的<a>
标签)。但是呢,在我实际接收到的数据中又包含多个\r\n\t
的空格或者换行及制表符标签。
我的处理办法是把包含的连续多个\r\n\t
的标签替换为一个\n
标签,然后再把\n
标签替换为<span></span>
来控制样式的展示。
故事的转折
逻辑设计的一切都好,但是在替换多个连续的\r\n\t
标签替换时,总是会在替换结束依旧存在多个\n
标签,这样就会造成我最终呈现的<span></span>
标签会出现连续多个,样式就会在某些细节上变得不可控。
正则替换之路
JSON数据示例
[
{
"id": 26,
"name": "那年,我曾爱过你",
"content": "\r\n\r\n\r\n\r\n那年,我曾爱过你</a>点击查看原文\r\n\r\n\t那年她说她怀孕了。\r\n\t她失去了一双眼睛和一个孩子;\r\n\r\n\t那年她逃走了。\r\n\t她失去了一颗子宫和一条命……\r\n\r\n\t陆晓死了,死在一场大火中,萧楚北站在漂泊的风雨下,\r\n\r\n\t对着墓碑上微笑的少女,跪地不起:晓晓,我后悔了……\r\n\r\n\t\r\n</p>",
"createTime": "2018-12-07 18:27:34.0",
"picArr": [
"http://ttak-novel-pic.oss-cn-hangzhou.aliyuncs.com/ad_subject/b57b3c3afa0a11e8a1f100163e0e3021.jpg"
]
},
{
"id": 25,
"name": "笙歌落尽长生花",
"content": "\r\n\t她出生在狗窝,3岁后被虐待长大……\r\n\r\n\t终于功成名就,可历史总是惊人的相似,谁也无法逃出其中的轮回……\r\n\r\n\t飞鸟尽,良弓藏;狡兔死,走狗烹\r\n\r\n\t作为大将之女,她一心辅佐他登上帝位!\r\n\r\n\t大婚之日,心念之人却求娶了另一个恨她入骨的女人,让她国破家亡。\r\n\r\n\t她声声质问心如刀绞:“你我是三书六礼定下的亲事,我才是你名正言顺的妻子啊。”\r\n\r\n\t他落拓而立,怀拥佳人,话语冷然,“我是答应要娶你,可没说,只娶你一人!”\r\n\r\n\t她苦笑,我允许你有三宫六院!可为什么偏偏是她?\r\n\r\n\t也许,一切从开始就错了……\r\n\r\n\t猛戳↓↓↓\r\n\r\n\t<a href=\"http://m.tiantianaikan.com/read/209997/1.shtml\" target=\"_blank\">《笙歌落尽长生花》</a>查看完整原文\r\n\r\n\t爱别离,怨憎会,求不得。人生七苦,慕歌儿都一一尝过了,她喜欢那个宛若长生花般的男子,多年以后,长生花落,情归何处?\r\n\r\n\t既然你无情,我定也不会纠缠你,此生,不复相见……\r\n</p>",
"createTime": "2018-12-07 17:55:36.0",
"picArr": [
"http://ttak-novel-pic.oss-cn-hangzhou.aliyuncs.com/ad_subject/3e47fd28fa0611e8a1f100163e0e3021.jpg"
]
}
]
其实,在整个JSON中,我们本篇需要处理的对象就是content字段。以以下简化变量来示例:
var cont = "\r\n\r\n\t终于功成名就,可历史总是惊人的相似,谁也无法逃出其中的轮回……\r\n\r\n\t飞鸟尽,良弓藏;狡兔死,走狗烹\r\n\r\n\t作为大将之女,她一心辅佐他登上帝位!\r\n\r\n\t她声声质问心如刀绞:“你我是三书六礼定下的亲事,我才是你名正言顺的妻子啊。”\r\n\r\n\t他落拓而立,怀拥佳人,话语冷然,“我是答应要娶你,可没说,只娶你一人!”\r\n\r\n\t她苦笑,我允许你有三宫六院!可为什么偏偏是她?\r\n\r\n\t也许,一切从开始就错了……\r\n\r\n\t猛戳↓↓↓\r\n\r\n\t<a href=\"http://m.tiantianaikan.com/read/209997/1.shtml\" target=\"_blank\">《笙歌落尽长生花》</a>查看完整原文\r\n\r\n\t爱别离,怨憎会,求不得。人生七苦,慕歌儿都一一尝过了,她喜欢那个宛若长生花般的男子,多年以后,长生花落,情归何处?</p>";
中间定稿方案
var con = cont.replace(/\n\s*\r|\r\n|\r|\t|\n|\n\n/g, '\n').replace(/\n\n|\n+/g, '\n').replace(/\n/g, '<span class="space1 space"></span>');
简述思路如下:
- 1.先将任意多个连续
\n
或者\r
或者\r\n
或者\t
或者\n
或者\n\n
替换为\n
- 2.此时,若替换正确,替换后的
con
中应当是只包含\n
或者\n\n
的存在 - 3.将以上两种情况替换为
\n
- 4.将
\n
替换为<span></span>
在控制台验证了下,发下我们这种方法,依然得不到满意的效果
终极方案(暂定)
var con = cont.replace(/\t/g, ''); //去除空格
con = con.replace(/(\r\n)\s*/g,'\n'); // 连续出现的\r\n替换为\n
con = con.replace(/\n/g,'<span class="space1 space"></span>'); //把全局的\n替换为<span></span>
在控制台验证了下,目前是可行的,连续存在的换行等已经替换为只保留一个\n
了。
思路直接写在代码注释里,很简单,不再赘述。为什么是暂定呢?因为这种方案,依旧需要时间来考验。
写在最后
中途相关正则替换
str = str.replace(/<[^>]+>|&[^>]+;/g,"").trim() //去掉所有的html标签和 之类的特殊符号
var con = cont.replace(/<[^>]+>|&[^>]+;|\t/g, ''); //去除html<>标签及空格
正则表达式的不断组合,不一样的组合都会产生不一样的效果。
console控制台也依然强大,某些代码我们直接通过console控制台来调试,反而可以看到更清晰的效果。