JS常规表达式在括号之前添加一些内容

时间:2019-02-11 14:03:37

标签: javascript regex gulp

我有以下字符串:

@something {
  color: red;
  background: yellow;
}

例如,我正在尝试在右括号之前添加heyaaa

@something {
  color: red;
  background: yellow;
  heyaaa
}

我正在使用gulp string replace在css文件中搜索@something,并在右括号前添加所需的heyaaa字符串。

我尝试了以下操作,但不起作用...

.pipe(replace('^(\@something\s*{(?:\n.*)*?\n)}', 'heyaaa'))

其他正则表达式也有效,因此我知道我的设置没有错。

3 个答案:

答案 0 :(得分:1)

问题出在replace函数的第二个参数中:您的代码将替换与heyaaa匹配的内容,而不是在您想要的位置插入heyaaa

您可以简单地执行以下操作,在第二个参数( replacement )中引用$1(第一个匹配的组):

const input = `@something {
  color: red;
  background: yellow;
}

@otherthing {
  color: red;
  background: yellow;
}
`

const regex = /^(\@something+\s*{(?:\n.*)*?\n)}/gm

const result0 = input.replace(regex, 'NEW TEXT TO BE INSERTED') // Original substitution
const result1 = input.replace(regex, '$1  NEW TEXT TO BE INSERTED\n}') // Fixed substitution

console.log(result0) // Original result
console.log(result1) // Fixed result

已更新:说明

我为多行正则表达式匹配添加了m后缀,并且为多个匹配添加了g后缀(没有reagexp仅适用于第一个匹配)。

如果您需要在每个CSS类的末尾添加NEW TEXT TO BE INSERTED,则应在正则表达式中将@something更改为@[^\s](请参见以下代码段)

const input = `@something {
  color: red;
  background: yellow;
}

@otherthing {
  color: red;
  background: yellow;
}
`

const regex = /^(\@[^\s]+\s*{(?:\n.*)*?\n)}/gm

const result = input.replace(regex, '$1  NEW TEXT TO BE INSERTED\n}') // Fixed substitution

console.log(result) // Fixed result

答案 1 :(得分:1)

您将捕获从开始到组中最后一个分号的部分,然后再匹配右花括号。但是,要使它重新获得替换,您必须参考捕获组。匹配的内容将不存在,因为您将替换匹配的内容。

要修复您的正则表达式,您可以捕获}组中的最后一个^(\@something\s*{(?:\n.*)*?\n)(}),而在替换组中请参考这些组。

const regex = /^(\@something\s*{(?:\n.*)*?\n)(})/gm;
const str = `@something {
  color: red;
  background: yellow;
}`;
const subst = `$1  heyaa\n$2`;
const result = str.replace(regex, subst);
console.log(result);

要考虑字符串的开头和最后一行的缩进,您可以匹配第一行,然后重复执行,而不必先查找后跟}的新行。

您可以在捕获组的开头捕获空白字符,并在替换组中引用该空白字符以匹配heyaaa的缩进:

^(@[^{]+{\s*(?:(?!\n})(\s+).*\n)*)(})

模式说明

  • ^开始
  • (捕获组
    • @[^{]+{\s*匹配@,而不是{ 1个以上。然后将{与0+乘以一个空白字符
    • (?:非捕获组
      • (?!\n})(\s+).*\n断言右边的内容不是换行符,后跟}。如果是这种情况,请匹配整行,然后再换一行
    • )*关闭组并重复0次以上
  • )关闭捕获组
  • (})捕获右括号
  • $结束

在替换中,您可以使用3个捕获组:

$1$2heyaaa\n$3

Regex demo

使用回调函数,您的代码可能类似于:

.pipe(replace(/^(@[^{]+{\s*(?:(?!\n})(\s+).*\n)*)(})/, function(_,g1,g2,g3) { 
    return g1 + g2 + "heyaaa\n" + g3; }
    )
)

const regex = /^(@[^{]+{\s*(?:(?!\n})(\s+).*\n)*)(})/gm;
const str = `@something {
  color: red;
  background: yellow;
}`;
const subst = `$1$2heyaaa\n$3`;
const result = str.replace(regex, subst);
console.log(result);

答案 2 :(得分:0)

一种方法是捕获组中最后}之前的所有内容,并在替换的回调函数中使用该捕获的组以及所需的值。

let str = `@something {
  color: red;
  background: yellow;
}`

let op = str.replace(/^(@something\s*[\w\W]+)}$/g,function(_,g1){
  return g1 + '  heyya,\n}'
})

console.log(op)