溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何用javascript正則實(shí)現(xiàn)移除注釋

發(fā)布時(shí)間:2021-11-15 14:32:25 來(lái)源:億速云 閱讀:202 作者:iii 欄目:web開(kāi)發(fā)

本篇內(nèi)容介紹了“如何用javascript正則實(shí)現(xiàn)移除注釋”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1 單行注釋

單行注釋要么占據(jù)一整行,要么處于某一行的***。

正常情況下不難,直接通過(guò)正則匹配,再用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);  // }

上面是成功的刪除了注釋?zhuān)贿^(guò)對(duì)于獨(dú)占一整行的注釋清理的不夠徹底,會(huì)留下空白行。實(shí)際上,行尾注釋前面的空白也被保留了下來(lái)。所以目標(biāo)稍稍提高,清除這些空白。操作起來(lái)也并不難,思路大致這樣:刪除整行,實(shí)際上是刪除本行末尾的換行符或上一行末尾的換行符。而換行符本身也屬于空白符。所以只需操作正則,匹配到注釋以及注釋前面所有的空白符即可,一箭雙雕。

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);  // }

如果在字符串中出現(xiàn)完整的URL地址,上面的正則會(huì)直接匹配而將其刪除。網(wǎng)上大多會(huì)將URL的格式特征(http://xxx):雙下劃線(xiàn)前面有冒號(hào),作為解決途徑加以利用。但這只是治標(biāo)不治本的做法,畢竟//以任何形式出現(xiàn)在字符串中是它的自由,我們無(wú)從干涉。

這樣問(wèn)題就轉(zhuǎn)變成:如何使正則匹配存在于引號(hào)外的雙下劃線(xiàn)?

想匹配被引號(hào)包圍,帶有雙下劃線(xiàn)的代碼塊比較簡(jiǎn)單:/".*\/\/.*"/mg。難點(diǎn)在于如何實(shí)現(xiàn)這個(gè)否定,即當(dāng)正則匹配到雙下劃線(xiàn)后,再判斷其是否在引號(hào)里面?絞盡腦汁,也上網(wǎng)查了很多,都沒(méi)有像樣的結(jié)果。靜心平氣,洗把臉?biāo)⑺⒀涝贈(zèng)_個(gè)頭冷靜之后,覺(jué)得單純使用正則的路已經(jīng)走不通了,得跳出這個(gè)圈。

就在***關(guān)頭,在那淫穢污濁的房間上方突然光芒萬(wàn)丈。我急忙護(hù)住了充滿(mǎn)血絲的眼睛,靜待其適應(yīng)后定睛一看。只見(jiàn)那里顯現(xiàn)出了一段文字(Chinese):孩兒啊,先將帶有//被引號(hào)包圍的字符串替換掉,去掉注釋后再還原,不就行了嗎?

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  // }    // 現(xiàn)在的方式。  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 };    }  }

是的,目標(biāo)達(dá)成了,老天眷顧啊!

另外,有一個(gè)需要優(yōu)化的地方:定義字符串的方式有三種 ' " ` ,目前我們只匹配了雙引號(hào)。

為了避免正則的記憶功能,都使用了正則字面量進(jìn)行測(cè)試。

--- 之前

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

?。?wèn)題到此結(jié)束了!

真的結(jié)束了嗎?不!我看了看時(shí)間:02:17,然后將眼鏡摘下,扯了張紙巾,拭去了幾顆淚水。

以下是接連解決的兩個(gè)問(wèn)題:貪婪模式和轉(zhuǎn)義字符。

--- STEP 1,由于正則的貪婪模式導(dǎo)致。 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,由定義字符串時(shí)其中的轉(zhuǎn)義字符導(dǎo)致。 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'"]

事情到這里,雖然勞累,但多少有些成就感,畢竟成功了。

可是,可是,可是在測(cè)試時(shí),竟然無(wú)意間發(fā)現(xiàn)一個(gè)無(wú)法逾越的障礙。就好比費(fèi)勁千辛萬(wàn)苦花費(fèi)無(wú)盡的財(cái)力物力之后,某某尤物終于愿意一同去情人旅館時(shí),卻發(fā)現(xiàn)家家爆滿(mǎn),沒(méi)有空余的房間。在強(qiáng)裝歡笑,玩命的哄騙著她,一家接連一家的尋找直到終于定到房間后,卻發(fā)現(xiàn)自己已然挺不起來(lái)了!

正則會(huì)將任意位置的引號(hào)作為查找的起始位置,它不在乎引號(hào)是成雙的道理。下面是一個(gè)示例。

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

不過(guò),問(wèn)題好歹在補(bǔ)過(guò)覺(jué)之后的 06:37 時(shí)得以解決。

思路是這樣的:雖然不能正確實(shí)現(xiàn)匹配帶有//被引號(hào)包圍的代碼塊(可能有方法,但能力有限),但是簡(jiǎn)化成匹配單純被引號(hào)包圍的代碼塊,是簡(jiǎn)單而且能正確做到的,雖然耗費(fèi)的內(nèi)存多了一些。另外,兩引號(hào)間也可能包含換行符,所以為其增加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 };    }  }

***補(bǔ)充一點(diǎn),單雙引號(hào)雖然也可以多行顯示,但其解析后實(shí)際是單行的。

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

2 多行注釋

啊!難點(diǎn)已經(jīng)解決,現(xiàn)在就可以悠哉悠哉的往前推進(jìn)了。

多行注釋與單行思路相同,只需在刪除注釋時(shí)多加一個(gè)匹配模式。中和兩者的最終代碼如下。

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正則實(shí)現(xiàn)移除注釋”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI