一个中高阶难度的 JavaScript 正则场景

问题描述

  这是一个字符串正则替换的问题,我自己想了一晚上也想不出用纯正则就能搞定这个问题。但这个问题看起确实不复杂,所以来思否求大佬解答。

  大概的特征是这样的,我需要在一个字符串文件中查找类似 start template template ... end 的字符串。其中 startend 是固定形式的字符串,template 是一个正则模式,我需要将位于 startend 之间的满足 template 模式的字符串前面加一个前缀 prefix,最后我希望文件中的满足条件的字符串被修改为 start prefix-template prefix-template ... end

问题实例

  下面是一个例子

var str = "lajishuju..Ejhohaodf98  a.length+b.length+10+:rowspan=a.length + b.length+ c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd";

  我希望能把 :rowspan=\d+ 之间的 x.length 形式的字符串修改为 sub.x.length。替换后的字符串应如下:

"lajishuju..Ejhohaodf98  a.length+b.length+10+:rowspan=sub.a.length + sub.b.length+ sub.c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd"

  明细字符串中加入了干扰字符串,如有 :rowspan= 开头却没有 \d+ 结尾的字符串,和有结尾却没开头的字符串。

我的想法

  我写出的正则只能利用 (?=) 断言排除有开头没结尾干扰字符串的干扰,无法判断是否具有合理的 :rowspan= 开头。
  恳请大佬指条明路,我和同学商量一下,他说不可能用一个正则一次解决这个问题。但我觉的这个模式特征这么明显,看起了也很简单,如此强大的正则不应该做不到,请大佬传道解惑!

另外

  题目中的“中高阶难度”是我大言不惭,毕竟我是个没怎么写过正则的菜鸡?,如有不当,请见谅!

阅读 3.8k
4 个回答
var str = "lajishuju..Ejhohaodf98 a.length+b.length+10+:rowspan=a.length + b.length+ c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd";

var r = str.replace(/(:rowspan=)(.+?)(?=\d*:rowspan)/g, function (...m)
{
    m[2] = m[2].replace(/\b([a-z]\w*\.length)/g, 'sub.$1');

    return m[1] + m[2];
});

console.log(r);
var str = "lajishuju..Ejhohaodf98 a.length+b.length+10+:rowspan=a.length + b.length+ c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd";
let reg=/:rowspan=[^\d]*?(?:([a-z])\.length\s*\+\s*)+(?:([a-z])\.length)[^\d]*?\d+/g;
let result=str.replace(reg,$1=>$1.replace(/([a-z]\.)(?=length)/g,'sub.$1'));
console.log(result);
//lajishuju..Ejhohaodf98 a.length+b.length+10+:rowspan=sub.a.length + sub.b.length+ sub.c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd
str.replace(/:rowspan=([^\d]+)\d/g, function($1){return $1.replace(/(\w.length)/g, '^^.$1')})

至少需要2个正则 因为一个正则没办法在选定范围的情况下同时匹配里面随机个数的表达式

var str = "lajishuju..Ejhohaodf98 a.length+b.length+10+:rowspan=a.length + b.length+ c.length20:rowspan=a.length+b.length lajishujudsjalfj)Ufaojd:rowspan=a.length + b.length2fsdfsdfsdf:rowspan=a.length + b.length2";
var gap = ':rowspan=';
var arrs = str.split(gap);
var head = arrs.shift();
var cnt = arrs.map(function(v){
  if(/\d+/.test(v)){
    var m = v.replace(/(\w*\.length)/g,'sub.$1');
    return gap + m;
  }else{
    return gap + v;
  }
});
var ret = head + cnt.join('');
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题