温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何用javascript正则实现移除注释

发布时间:2021-11-15 14:32:25 来源:亿速云 阅读:181 作者:iii 栏目:web开发

本篇内容介绍了“如何用javascript正则实现移除注释”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1 单行注释

单行注释要么占据一整行,要么处于某一行的***。

正常情况下不难,直接通过正则匹配,再用replace方法移除便可。

let codes = `    let name = "Wmaker"; // This is name.    if (name) {      // Print name.      console.log("His name is:", name);    }  `;    console.log( codes.replace(/\/\/.*$/mg, '') );   // 打印出:  // let name = "Wmaker";   // if (name) {  //     //   console.log("His name is:", name);  // }

上面是成功的删除了注释,不过对于独占一整行的注释清理的不够彻底,会留下空白行。实际上,行尾注释前面的空白也被保留了下来。所以目标稍稍提高,清除这些空白。操作起来也并不难,思路大致这样:删除整行,实际上是删除本行末尾的换行符或上一行末尾的换行符。而换行符本身也属于空白符。所以只需操作正则,匹配到注释以及注释前面所有的空白符即可,一箭双雕。

let codes = `    let name = "Wmaker"; // This is name.    if (name) {      // Print name.      console.log("His name is:", name);    }  `;    console.log( codes.replace(/\s*\/\/.*$/mg, '') );   // 打印出:  // let name = "Wmaker";  // if (name) {  //   console.log("His name is:", name);  // }

如果在字符串中出现完整的URL地址,上面的正则会直接匹配而将其删除。网上大多会将URL的格式特征(http://xxx):双下划线前面有冒号,作为解决途径加以利用。但这只是治标不治本的做法,毕竟//以任何形式出现在字符串中是它的自由,我们无从干涉。

这样问题就转变成:如何使正则匹配存在于引号外的双下划线?

想匹配被引号包围,带有双下划线的代码块比较简单:/".*\/\/.*"/mg。难点在于如何实现这个否定,即当正则匹配到双下划线后,再判断其是否在引号里面?绞尽脑汁,也上网查了很多,都没有像样的结果。静心平气,洗把脸刷刷牙再冲个头冷静之后,觉得单纯使用正则的路已经走不通了,得跳出这个圈。

就在***关头,在那淫秽污浊的房间上方突然光芒万丈。我急忙护住了充满血丝的眼睛,静待其适应后定睛一看。只见那里显现出了一段文字(Chinese):孩儿啊,先将带有//被引号包围的字符串替换掉,去掉注释后再还原,不就行了吗?

let codes = `    let name = "Wmaker"; // This is name.    if (name) {      // Print name.      console.log("His name is:", name);      console.log("Unusual situation, characters of // in quotation marks.");    }  `;    // 之前的方式。  console.log( codes.replace(/\s*\/\/.*$/mg, '') );  // 打印出:  // let name = "Wmaker"; // if (name) {  //   console.log("His name is:", name);  //   console.log("Unusual situation, characters of  // }    // 现在的方式。  console.log( removeComments(codes) );  // 打印出: // let name = "Wmaker";  // if (name) {  //   console.log("His name is:", name);  //   console.log("Unusual situation, characters of // in quotation marks.");  // }   function removeComments(codes) {    let {replacedCodes, matchedObj} = replaceQuotationMarksWithForwardSlash(codes);     replacedCodes = replacedCodes.replace(/\s*\/\/.*$/mg, '');    Object.keys(matchedObj).forEach(k => {      replacedCodes = replacedCodes.replace(k, matchedObj[k]);    });     return replacedCodes;     function replaceQuotationMarksWithForwardSlash(codes) {      let matchedObj = {};      let replacedCodes = '';           let regQuotation = /".*\/\/.*"/mg;      let uniqueStr = 'QUOTATIONMARKS' + Math.floor(Math.random()*10000);       let index = 0;      replacedCodes = codes.replace(regQuotation, function(match) {        let s = uniqueStr + (index++);        matchedObj[s] = match;        return s;      });       return { replacedCodes, matchedObj };    }  }

是的,目标达成了,老天眷顾啊!

另外,有一个需要优化的地方:定义字符串的方式有三种 ' " ` ,目前我们只匹配了双引号。

为了避免正则的记忆功能,都使用了正则字面量进行测试。

--- 之前

console.log( /".*\/\/.*"/mg.test(`'Unu//sual'`) ); // false  console.log( /".*\/\/.*"/mg.test(`"Unu//sual"`) ); // true  console.log( /".*\/\/.*"/mg.test(`\`Unu//sual\``) ); // false

--- 之后

console.log( /('|"|`).*\/\/.*\1/mg.test(`'Unu//sual'`) ); // true  console.log( /('|"|`).*\/\/.*\1/mg.test(`"Unu//sual"`) ); // true  console.log( /('|"|`).*\/\/.*\1/mg.test(`\`Unu//sual\``) ); // true

啊!问题到此结束了!

真的结束了吗?不!我看了看时间:02:17,然后将眼镜摘下,扯了张纸巾,拭去了几颗泪水。

以下是接连解决的两个问题:贪婪模式和转义字符。

--- STEP 1,由于正则的贪婪模式导致。 let codes = `   let str = 'abc//abc'; // abc' `; console.log( codes.match(/('|"|`).*\/\/.*\1/mg) ); // ["'abc//abc'; // abc'"]  -- 解决  let codes = `   let str = 'abc//abc'; // abc' `; console.log( codes.match(/('|"|`).*?\/\/.*?\1/mg) ); // ["'abc//abc'"]   --- STEP 2,由定义字符串时其中的转义字符导致。 let codes = `   let str = 'http://x\\'x.com'; // 'acs `; console.log( codes.match(/('|"|`).*?\/\/.*?\1/mg) ); // ["'http://x\'", "'; // '"]  -- 解决  let reg = /(?<!\\)('|"|`).*?\/\/.*?(?<!\\)\1/mg; let codes = `   let str = 'http://x\\'x.com'; // 'acs `; console.log( codes.match(reg) ); // ["'http://x\'x.com'"]

事情到这里,虽然劳累,但多少有些成就感,毕竟成功了。

可是,可是,可是在测试时,竟然无意间发现一个无法逾越的障碍。就好比费劲千辛万苦花费无尽的财力物力之后,某某尤物终于愿意一同去情人旅馆时,却发现家家爆满,没有空余的房间。在强装欢笑,玩命的哄骗着她,一家接连一家的寻找直到终于定到房间后,却发现自己已然挺不起来了!

正则会将任意位置的引号作为查找的起始位置,它不在乎引号是成双的道理。下面是一个示例。

let reg = /(?<!\\)('|"|`).*?\/\/.*?(?<!\\)\1/mg;  let codes = `    let str = "abc"; // "  `;  console.log( codes.match(reg) ); // [""abc"; // ""]

不过,问题好歹在补过觉之后的 06:37 时得以解决。

思路是这样的:虽然不能正确实现匹配带有//被引号包围的代码块(可能有方法,但能力有限),但是简化成匹配单纯被引号包围的代码块,是简单而且能正确做到的,虽然耗费的内存多了一些。另外,两引号间也可能包含换行符,所以为其增加s模式:.代表全部字符。下面是去除单行注释的最终代码。

let codes = `    let name = "Wmaker"; // This is name.    let str = 'http://x\\'x.com' + " / / " + '/"/"/'; // '; // " "    if (name) {      // Print name.      console.log("His name is:", name);      console.log("Unusual situation, characters of // in quotation marks.");    } `;   console.log(removeComments(codes));  // 打印出:  // let name = "Wmaker";  // let str = 'http://x\'x.com' + " / / " + '/"/"/';  // if (name) {  //   console.log("His name is:", name);  //   console.log("Unusual situation, characters of // in quotation marks.");  // }  function removeComments(codes) {    let {replacedCodes, matchedObj} = replaceQuotationMarksWithForwardSlash(codes);     replacedCodes = replacedCodes.replace(/\s*\/\/.*$/mg, '');    Object.keys(matchedObj).forEach(k => {      replacedCodes = replacedCodes.replace(k, matchedObj[k]);    });     return replacedCodes;     function replaceQuotationMarksWithForwardSlash(codes) {      let matchedObj = {};      let replacedCodes = '';          let regQuotation = /(?<!\\)('|"|`).*?(?<!\\)\1/smg;      let uniqueStr = 'QUOTATIONMARKS' + Math.floor(Math.random()*10000);       let index = 0;      replacedCodes = codes.replace(regQuotation, function(match) {        let s = uniqueStr + (index++);        matchedObj[s] = match;        return s;      });       return { replacedCodes, matchedObj };    }  }

***补充一点,单双引号虽然也可以多行显示,但其解析后实际是单行的。

let codes = "' \    Wmaker \  '";  codes.match( /(?<!\\)('|"|`).*?(?<!\\)\1/smg ); // ["'   Wmaker '"]

2 多行注释

啊!难点已经解决,现在就可以悠哉悠哉的往前推进了。

多行注释与单行思路相同,只需在删除注释时多加一个匹配模式。中和两者的最终代码如下。

let codes = `    let name = "Wmaker"; // This is name.    let str = 'http://x\\'x.com' + " / / " + '/"/"/'; // '; // " "    let str = 'http://x\\'x./*a*/com' + " / / " + '/"/"/'; // '; // "/*sad*/ "    if (name) {      // Print name.      /* Print name. */      console.log("His name is:", name);      console.log("Unusual situation, characters of // in quotation marks.");      /*       * Others test.       */      console.log("Unusual situation, characters of /* abc */ in quotation marks.");    }  `;    console.log(removeComments(codes));  // 打印出:  // let name = "Wmaker";  // let str = 'http://x\'x.com' + " / / " + '/"/"/';  // let str = 'http://x\'x./*a*/com' + " / / " + '/"/"/';  // if (name) {  //   console.log("His name is:", name);  //   console.log("Unusual situation, characters of // in quotation marks.");  //   console.log("Unusual situation, characters of /* abc */ in quotation marks."); // }   function removeComments(codes) {    let {replacedCodes, matchedObj} = replaceQuotationMarksWithForwardSlash(codes);     replacedCodes = replacedCodes.replace(/(\s*\/\/.*$)|(\s*\/\*[\s\S]*?\*\/)/mg, '');    Object.keys(matchedObj).forEach(k => {      replacedCodes = replacedCodes.replace(k, matchedObj[k]);    });    return replacedCodes;    function replaceQuotationMarksWithForwardSlash(codes) {      let matchedObj = {};      let replacedCodes = '';           let regQuotation = /(?<!\\)('|"|`).*?(?<!\\)\1/smg;      let uniqueStr = 'QUOTATIONMARKS' + Math.floor(Math.random()*10000);       let index = 0;      replacedCodes = codes.replace(regQuotation, function(match) {      let s = uniqueStr + (index++);      matchedObj[s] = match;      return s;      });      return { replacedCodes, matchedObj };    }  }

“如何用javascript正则实现移除注释”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI