kotlin String :: replace删除转义序列?

问题描述 投票:2回答:3

我正在使用正则表达式尝试一些字符串操作,但我没有得到预期的输出

var myString = "/api/<user_id:int>/"
myString.replace(Regex("<user_id:int>"), "(\\d+)")

这应该给我像/api/(\d+)/,但我得到/api/(d+)/

但是,如果我像var a = "\d+"一样直接创建一个转义字符串 我得到正确的输出\d+(我可以进一步用来创建一个正则表达式模式) 这是由于String::replace的工作方式? 如果是这样,这不是一个错误,为什么它会删除我的转义序列?

regex kotlin escaping
3个回答
5
投票

要替换文字字符串,请使用:

myString.replace(Regex("<user_id:int>"), Regex.escapeReplacement("(\\d+)"))

有关详细信息,这就是kotlin Regex.replace正在做的事情:

  Pattern nativePattern = Pattern.compile("<user_id:int>");
  String m = nativePattern.matcher("/api/<user_id:int>/").replaceAll("(\\d+)");

  -> m = (d+) 

来自Matcher.replaceAll() javadoc:

请注意,替换字符串中的反斜杠()和美元符号($)可能会导致结果与将其视为文字替换字符串时的结果不同。如上所述,美元符号可被视为对捕获的子序列的引用,反斜杠用于替换替换字符串中的文字字符。

上面对Regex.escapeReplacement的调用确实如此,将(\\d+)转换为(\\\\d+)


2
投票

您正在使用.replace重载,它将正则表达式作为第一个参数,因此,第二个参数被解析为正则表达式替换模式。在正则表达式替换模式中,\字符是特殊的,它可以逃脱美元符号被视为文字美元符号。因此,正则表达式替换模式中的字面反斜杠应该加倍。

你可能会用

myString.replace(Regex("<user_id:int>"), """(\\d+)""")

每当您必须使用正则表达式进行搜索和替换并且替换模式是动态值时,您应该使用Regex.escapeReplacement(请参阅GUIDO's answer)。

但是,您要用另一个文字值替换文字值,您不必在此处使用正则表达式:

myString.replace("<user_id:int>", """(\d+)""")

this Kotlin demo屈服于/api/(\d+)/

请注意使用原始字符串文字,其中反斜杠被解析为文字反斜杠。


0
投票

作为正则表达式引擎的替换看到它被内插为双引号字符串。 每个正则表达式引擎都是如此。

这是为了区分控制代码,如制表符换行符或回车符。

这里没什么特别的。

因此,发动机的替代品希望看到它是(\\d+)

语言插入相同。

最终结果repl_str = "(\\\\d+)"

© www.soinside.com 2019 - 2024. All rights reserved.