正则表达式匹配代码块的注释

Posted Test_user

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式匹配代码块的注释相关的知识,希望对你有一定的参考价值。

使用正则内部的逻辑短路匹配之一举多得

用多分支来排除,像if-else那样不用写出完全的条件。
小而广的条件有时不仅能匹配到最终目标,而且还能锦上添花(一举多得):

regexp = /str|regexp|lineannotaion|blockannotation|tampstring/g

let tmp=\'\', str = `
    ${tmp+\'\\`\'+"${}"+
    `${tmp}`+ /*A*/
    (tmp={\'a\':/(?<!x`)/g}["a"]) //B
}\'c\' \\" <d> & //  e /*f*/`,  //  g
reg = /(?<!\\\\)\\/(?![^\\/\\*])[\\s\\S]+?(?<!\\\\)\\//g;
//*/ h
    str; reg = /c/g, str = ``
/*/  j
    k //KK
//*/
str = "\\"http://\'xxxx\'\\/\\"";
str = `.replace(/&/g, \'&amp;\').replace(/</g, \'&lt;\').replace(/\\u00a0/g, \' \')${`l`+str}`
str = \'\\
   \\\' //n"`\\
\' /* // */

匹配任意字符

/[\\s\\S]/g
/[^]/g

匹配单行注释

/\\/\\/.*/g

匹配多行注释

/\\/\\*[^]*?\\*\\//g

匹配字符串

/(\'|"|`)[^]*?(?<!\\\\)\\1/g
/\'\'|``|""|(\'|"|`)[^]*?[^\\\\]\\1/g
/\'\'|""|(\'|")[^]*?[^\\\\]\\1|`(?:\\\\[\\s\\S]|\\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\\${)[^\\\\`])*`/g

字符串模板${}内部可能还会出现字符串模板和正则表达式内存在未转义的\\`
书写简单的字符串模板时使用第二个正则表达式应该是没大问题的

匹配正则表达式

/\\/.*?[^\\\\]\\//g

替换需要转义的字符

.replace(/&|<|\\u00a0/g,m=>
    m  ==\'&\' ? "&amp;"
    : m==\'<\' ? "&lt" 
    : /\\u00a0/.test(m) 
    ? \' \' : m
)

基本实现

CODE_javascript
.replace(/&|<|\\u00a0/g,m=> // 匹配需要转义的html符号
    m  ==\'&\' ? "&amp;" : m==\'<\' ? "&lt" : /\\u00a0/.test(m) ? \' \' : m
)
.replace(
    // /\\/\\/.*|\\/\\*[^]*?\\*\\/|\'\'|``|""|(\'|"|`)[^]*?[^\\\\]\\1|\\/.*?[^\\\\]\\//g, // ${}内部不能再嵌套模板字符串,内部使用正则时要转义`,像这样 ${"helo".match(/\\`/)[0]}
    /\\/\\/.*|\\/\\*[^]*?\\*\\/|\\/.*?[^\\\\]\\/|\'\'|""|(\'|")[^]*?[^\\\\]\\1|`(?:\\\\[\\s\\S]|\\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\\${)[^\\\\`])*`/g,
    (m,a,b,c,d,e,f,g)=>{
    
    // return /\\/\\*|\\/\\//.test(m.slice(0, 2)) 
    return m.slice(0,2) == "//" ||  m.slice(0,2) == "/*"
    
    // ? (!b || /\\r|\\n/.test(c[b-1]) ? "<span class=\\"annotation\\">"+m+"</span>" : "<span class=\\"annotation-sub\\">"+m+"</span>")
    ? "<span class=\\"annotation\\">"+m+"</span>"
    : m
})

测试版

<link rel="icon" href="data:base64">
    <title>CL Testy</title>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<body>

<textarea style="white-space:pre;width:100%;height:400px"></textarea>
<pre style="padding:0.5em;background:rgba(0,0,0,0.05);overflow:scroll;scrollbar-width:none"></pre>
<article></article>

<script>"use strict";
    let PXHR=(e,t=!0)=>{return new Promise((n,s)=>{let a=new XMLHttpRequest;a.onreadystatechange=(()=>{4==a.readyState&&(200==a.status||304==a.status?n(a):s(a))}),a.open("GET",e,t),a.send()})},
        $ = s => document.querySelector(s),
        _ = s => s.replace(/\\/\\/.*|\\/\\*[^]*?\\*\\/|\\/.*?[^\\\\]\\/|\'\'|""|(\'|")[^]*?[^\\\\]\\1|`(?:\\\\[\\s\\S]|\\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\\${)[^\\\\`])*`/g, (m,a,b,c)=>{
            return /\\/\\*|\\/\\//.test(m.slice(0, 2)) ?
                ( !b || /\\r|\\n/.test(c[b-1])
                    ? "<span class=\\"annotation\\">"+m+"</span>" 
                    : "<span class=\\"annotation-sub\\">"+m+"</span>"
                )
            :a={
                \'\\\'\':"<span class=char>"+m+"</span>",
                \'\\"\':"<span class=string>"+m+"</span>",
                \'/\' :"<span class=\'regexp\'>"+m+"</span>",
                \'\\`\':"<span class=\'blockstr\'>"+m+"</span>"
            }[m[0]] || m
        }),
        __= s => s.replace(/&|<|\\u00a0/g,m=> m==\'&\' ? "&amp;" : m==\'<\' ? "&lt;" : /\\u00a0/.test(m) ? \' \' : m);
    
    PXHR(location.origin+"/testy.js").then( res =>{
        document.querySelector("pre").innerHTML 
        = $("textarea").value
        = _(__(res.responseText))
    })
    PXHR(location.origin+"/testy.md").then( res =>{
        document.querySelector("article").innerHTML 
        = marked(res.responseText);
        document.querySelector(".language-js").innerHTML
        = _(__(document.querySelector(".language-js").textContent))
    })
</script>
</body></html>
<style>
    .annotation{background:#62a562}
    .annotation-sub{background:#ccc}
    .char{background:skyblue}
    .string{background:rgb(172, 134, 172)}
    .blockstr{background:orange}
    .regexp{background:pink}
</style>

测试的js和md文件

let tmp=\'\', str = `
    ${tmp+\'\\`\'+"${}"+
    `${tmp}`+ /*A*/
    (tmp={\'a\':/(?<!x`)/g}["a"]) //B
}\'c\' \\" <d> & //  e /*f*/`,  //  g
reg = /(?<!\\\\)\\/(?![^\\/\\*])[\\s\\S]+?(?<!\\\\)\\//g;
//*/ h
    str; reg = /c/g, str = ``
/*/  j
    k //KK
//*/
str = "\\"https://\'crawly.top\'\\/\\"";
str = `.replace(/&/g, \'&amp;\').replace(/</g, \'&lt;\').replace(/\\u00a0/g, \' \')${`l`+str}`
str = \'\\
   \\\' //n"`\\
\' /* // */

以上是关于正则表达式匹配代码块的注释的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式到源代码注释

匹配多行文本块的正则表达式

使用 sed 或 Perl 来注释 XML 块的正则表达式

循环通过 python 正则表达式匹配

正则表达式匹配特定的 URL 片段而不是所有其他 URL 可能性

正则表达式在 C# 源文件中查找注释