JSON字符串正则表达式替换多余空格及换行

JSON字符串正则表达式替换多余空格及换行

  1. 小说前端 🧩
  2. 6 years ago
  3. 7 min read

正则表达式是功能强大的利器,无关乎语言,无关乎场景。

故事的背景

但凡是故事,都会有背景,这段故事的背景大致如下:服务端通过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>

在控制台验证了下,发下我们这种方法,依然得不到满意的效果

replace01.png | center | 747x101

终极方案(暂定)

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了。

replace01.png | center | 747x101

思路直接写在代码注释里,很简单,不再赘述。为什么是暂定呢?因为这种方案,依旧需要时间来考验。

写在最后

中途相关正则替换

str = str.replace(/<[^>]+>|&[^>]+;/g,"").trim()  //去掉所有的html标签和&nbsp;之类的特殊符号
var con = cont.replace(/<[^>]+>|&[^>]+;|\t/g, ''); //去除html<>标签及空格

正则表达式的不断组合,不一样的组合都会产生不一样的效果。

console控制台也依然强大,某些代码我们直接通过console控制台来调试,反而可以看到更清晰的效果。

正则表达式 regular JavaScript