除了GStrings之外,用双引号替换双引号字符串

时间:2017-04-06 13:28:11

标签: regex intellij-idea groovy

我的OCD已经变得更好了,我正在通过我的常规代码库将简单的字符串替换为双引号,并将它们替换为单引号字符串。

但是,我想避免实际包含美元符号和变量的GStrings。

我正在使用IntelliJ进行替换,以下几乎可以正常工作:

From: "([^$\"\n\r]+)"
  To: '$1'

它捕获没有任何美元的字符串,但只是部分跳过包含它们的任何字符串。

例如,它匹配两个双引号字符串之间的引号:

foo("${var}": "bar")
           ^^^^

是否可以创建一个跳过包含美元的整个字符串的正则表达式,因此在上述情况下它会跳过"${var}"并选择"bar",而不是错误地选择": "

编辑:这是一段试图反对

的代码
table.columns.elements.each{ columnName, column ->
  def columnText = "${columnName} : ${column.dataType}"
  cols += "${columnText}\n"
  if (columnText.length() > width) {
    width = columnText.length()
  }
  height++
}
builder."node"("id": table.elementName) {
  builder."data"("key": "d0") {
    builder."y:ShapeNode"()
  }
}

def foo() {
  def string = """
a multiline quote using triple quotes with ${var} gstring vars in.
"""
}

2 个答案:

答案 0 :(得分:2)

单独进行单引号和三引号替换。

单引号:

在点击后使用前面的偶数引号。背后的负面观察会使其与三重引用字符串的内部引号相匹配。

Find: (?<!")"([^"$]*)"(?=(?:(?:[^"\r\n]*"){2})*[^"]*$)
Replace: '$1'

请参阅live demo

三重引号:

对三重引用的字符串使用更简单的匹配,因为它们在各自的行上。

Find: """([^"$]*?)"""
Replace: '''$1'''

请参阅live demo,其中包含一个包含变量的三引号字符串。

答案 1 :(得分:1)

您需要确保第一个引用来自偶数引号:

^[^\n\r"]*(?:(?:"[^"\n\r]*){2})*"([^$\"\n\r]+)"

Here你可以玩它。

说明:

  • ^[^"\n\r]* - 开头的一些非引号
  • "[^"\n\r]* - 引用,然后是更多非引用
  • (?:"[^"\n\r]*){2} - 让我们有两个
  • (?:(?:...)) - 实际上,让我们拥有0,2,4,6 ...... ......无论多少
  • 然后你的正则表达式匹配正确的字符串:"([^$\"\n\r]+)"

如果intellij支持,那么你可以通过用原子组(?:...)替换非捕获组(?>...)来加快速度。

此正则表达式找到行中的最后一个字符串,因此您必须多次运行替换。

更新

使用换行符更新了否定的字符类。现在它也适用于多行文本。但是,你必须多次运行它,因为它每行只找到一个字符串。