如何在 Scala 中将第 n 次出现的特殊字符(例如竖线定界符)替换为另一个字符?
How do I replace the nth occurrence of a special character, say, a pipe delimiter with another in Scala?
我是使用 Scala 的 Spark 新手,我需要用换行符替换第 n 次出现的定界符。
到目前为止,我已经成功地在 管道分隔符之后输入了一个新行。
我无法 替换 分隔符本身。
我的输入字符串是
val txt = "January|February|March|April|May|June|July|August|September|October|November|December"
println(txt.replaceAll(".\|", "[=10=]\n"))
以上语句生成以下输出。
January|
February|
March|
April|
May|
June|
July|
August|
September|
October|
November|
December
我参考了 https://salesforce.stackexchange.com/questions/189923/adding-comma-separator-for-every-nth-character 的建议,但是当我在花括号中输入数字时,我最终只在分隔符后的 2 个字符后添加换行符.
我希望我的输出如下所示。
January|February
March|April
May|June
July|August
September|October
November|December
如何更改我的正则表达式以获得所需的输出?
更新:
我的朋友建议我尝试以下语句
println(txt.replaceAll("(.*?\|){2}", "[=13=]\n"))
这产生了以下输出
January|February|
March|April|
May|June|
July|August|
September|October|
November|December
现在我只需要去掉每行末尾的管道符号。
您可以先使用“|”拆分字符串获取字符串数组,然后遍历它以执行所需的逻辑并根据需要获取输出。
val txt = "January|February|March|April|May|June|July|August|September|October|November|December"
val out = txt.split("\|")
var output: String = ""
for(i<-0 until out.length -1 by 2){
val ref = out(i) + "|" + out(i+1) + "\n"
output = output + ref
}
val finalout = output.replaceAll("\"\"","") //just to remove the starting double quote
println(finalout)
您想将第二个柱 |
移到捕获组之外。
txt.replaceAll("([^|]+\|[^|]+)\|", "\n")
//val res0: String =
// January|February
// March|April
// May|June
// July|August
// September|October
// November|December
正则表达式解释(正则表达式不是 Scala)
(
- 启动捕获组
[^|]
- 任何字符,只要不是小节 |
字符
[^|]+
- 1 个或多个(任何)非条形字符
\|
- 后跟一个条形字符 |
[^|]+
- 后跟 1 个或多个非条形字符
)
- 关闭捕获组
\|
- 后跟一个条形字符(不在捕获组中)
"\n"
- 用第一个 </code> 捕获组替换整个匹配字符串(<code>[=24=]
是整个匹配字符串),然后是换行符
更新
对于 N 次重复的一般情况,正则表达式变得有点麻烦,至少如果您尝试使用单个正则表达式公式来做到这一点。
最简单的事情(不是最有效但代码简单)是遍历 String
两次。
val n = 5
txt.replaceAll(s"(\w+\|){$n}", "[=11=]\n")
.replaceAll("\|\n", "\n")
//val res0: String =
// January|February|March|April|May
// June|July|August|September|October
// November|December
我是使用 Scala 的 Spark 新手,我需要用换行符替换第 n 次出现的定界符。
到目前为止,我已经成功地在 管道分隔符之后输入了一个新行。 我无法 替换 分隔符本身。
我的输入字符串是
val txt = "January|February|March|April|May|June|July|August|September|October|November|December"
println(txt.replaceAll(".\|", "[=10=]\n"))
以上语句生成以下输出。
January|
February|
March|
April|
May|
June|
July|
August|
September|
October|
November|
December
我参考了 https://salesforce.stackexchange.com/questions/189923/adding-comma-separator-for-every-nth-character 的建议,但是当我在花括号中输入数字时,我最终只在分隔符后的 2 个字符后添加换行符.
我希望我的输出如下所示。
January|February
March|April
May|June
July|August
September|October
November|December
如何更改我的正则表达式以获得所需的输出?
更新: 我的朋友建议我尝试以下语句
println(txt.replaceAll("(.*?\|){2}", "[=13=]\n"))
这产生了以下输出
January|February|
March|April|
May|June|
July|August|
September|October|
November|December
现在我只需要去掉每行末尾的管道符号。
您可以先使用“|”拆分字符串获取字符串数组,然后遍历它以执行所需的逻辑并根据需要获取输出。
val txt = "January|February|March|April|May|June|July|August|September|October|November|December"
val out = txt.split("\|")
var output: String = ""
for(i<-0 until out.length -1 by 2){
val ref = out(i) + "|" + out(i+1) + "\n"
output = output + ref
}
val finalout = output.replaceAll("\"\"","") //just to remove the starting double quote
println(finalout)
您想将第二个柱 |
移到捕获组之外。
txt.replaceAll("([^|]+\|[^|]+)\|", "\n")
//val res0: String =
// January|February
// March|April
// May|June
// July|August
// September|October
// November|December
正则表达式解释(正则表达式不是 Scala)
(
- 启动捕获组[^|]
- 任何字符,只要不是小节|
字符[^|]+
- 1 个或多个(任何)非条形字符\|
- 后跟一个条形字符|
[^|]+
- 后跟 1 个或多个非条形字符)
- 关闭捕获组\|
- 后跟一个条形字符(不在捕获组中)"\n"
- 用第一个</code> 捕获组替换整个匹配字符串(<code>[=24=]
是整个匹配字符串),然后是换行符
更新
对于 N 次重复的一般情况,正则表达式变得有点麻烦,至少如果您尝试使用单个正则表达式公式来做到这一点。
最简单的事情(不是最有效但代码简单)是遍历 String
两次。
val n = 5
txt.replaceAll(s"(\w+\|){$n}", "[=11=]\n")
.replaceAll("\|\n", "\n")
//val res0: String =
// January|February|March|April|May
// June|July|August|September|October
// November|December