如何使用正则表达式替换和片段将行填充到一定长度

How to pad out line to certain length using regex replace and snippets

// My Section -----------------------------------------------------------------

以上是想要的结果


想象一下这个场景

// ----------------------------------------------------------------------------
// firebase

// ----------------------------------------------------------------------------
// utils

可以使用例如这个正则表达式 /(^.{20}).*$// 将 trim 行达到一定长度,这将给出

// -----------------
// firebase

// -----------------
// utils

But what if I want to fill the other lines instead up to the set length like this in one run? Is that possible?

  • one regex for only the right fill, not the trim
// -----------------
// firebase --------

// -----------------
// utils -----------

很久以前,我在做一些正则表达式忍者挑战,我们应该做数学,所以....正则表达式很神奇。


我最终想要实现的是一个 VSCode 片段,它允许我写:My Section --
然后触发一个片段,将插入的文本转换为包含

的 80 个字符宽的评论
// My Section -----------------------------------------------------------------

https://code.visualstudio.com/docs/editor/userdefinedsnippets

可以使用replace的回调函数,根据长度替换值

let str = `// ----------------------------------------------------------------------------
// firebase

// ----------------------------------------------------------------------------
// utils`

let final = str.replace(/^.*$/gm, (match)=>{
  return match.length === 0 ? match : match.length > 20 ? match.substr(0,20) : match + `-`.repeat(20-match.length)
})

console.log(final)

我怀疑你是否可以在没有 运行 一些代码的情况下一步完成你想做的事情。但是您可以使用宏来完成,这样您就可以同时触发多个步骤。在此示例中,我使用的是宏扩展 multi-command,但还有其他宏扩展。

在你的 settings.json:

"multiCommand.commands": [

 {
   "command": "multiCommand.commentSection",
   // "interval": 750,  // you don't need this, just for illustration

   "sequence": [  
     "cursorEnd",            
     {
       "command": "type",  // add 75 -'s'
       "args": {
         "text": " ---------------------------------------------------------------------------"
       }
     },

     "editor.action.addCommentLine",

     // select this wrapped line so the next snippet can use TM_SELECTED_TEXT
     "cursorHomeSelect",
     "cursorHomeSelect",

     {
       "command": "editor.action.insertSnippet",  // trim to first 80 characters
       "args": {
         "snippet": "${TM_SELECTED_TEXT/(.{80}).*//g}",
       }
     }
   ]
 }
],

然后您在 keybindings.json

中选择的任何键绑定
{
  "key": "ctrl+alt+-",
  "command": "extension.multiCommand.execute",
  "args": { "command": "multiCommand.commentSection" }
},

基本思路是添加过多的连字符 - 比如 75 - 然后 select 整个换行并仅保留前 80 个字符,从而修剪尾随连字符以填充到总共 80 个字符这条线。

它也适用于空行,如演示结尾所示。

添加另一个与我之前的宏扩展答案截然不同的答案。

我做了一个扩展,Find and Transform,它很容易做到这一点,因为你可以在 find/replace.

中执行 javascript 运算,比如数学运算

使用此键绑定(在您的 keybindings.json 中):

{
  "key": "alt+r",                      // whatever keybinding you want
  "command": "findInCurrentFile",
  "args": {
       
    "find": "(${TM_CURRENT_LINE})",
    
    "replace": "${LINE_COMMENT} $${ return ' '.padEnd(79 - '${LINE_COMMENT}'.length, '-') }$$",

    "isRegex": true,
    "restrictFind": "line"    // can have multiple lines with a cursor
}

或者,您可以将它(以稍微不同的形式)放入您的 settings.json 中,从中创建一个命令 - 这样可以从命令面板访问并且更容易在 set-ups 之间同步.


"replace": "${LINE_COMMENT} $${ return ' '.padEnd(79 - '${LINE_COMMENT}'.length, '-') }$$",

替换为当前编辑器语言的行注释。添加一个由 $${...}$$ 表示的 javascript 操作以使解析更容易。

return ' '.padEnd(79 - '${LINE_COMMENT}'.length, '-') return 捕获组 1(后跟一个 space)并填充到总共 80 个字符(必须考虑行注释字符后的 space // )。减去可能因语言而异的行注释字符的长度。

请注意,表示字符串的项目,如 ${LINE_COMMENT} 由单引号表示为字符串(您也可以使用反引号)。否则 javascript 会将它们解释为未知变量名称。

如果您不关心使用不同样式和长度的行注释,您可以使用更简单的:

"replace": "// $${ return ''.padEnd(79, '-') }$$",