Regex 如何替换仅出现在事物之间的分隔符?
我有一个使用此数据的用例:Regex 如何替换仅出现在事物之间的分隔符?,regex,scala,apache-spark,regex-lookarounds,regexp-replace,Regex,Scala,Apache Spark,Regex Lookarounds,Regexp Replace,我有一个使用此数据的用例: 1. "apple+case" 2. "apple+case+10+cover" 3. "apple+case+10++cover" 4. "+apple" 5. "iphone8+" 目前,我这样做是为了将+替换为空格,如下所示: def normalizer(value: String): String = { if (value == null) { null } else { value.replaceAll("\\
1. "apple+case"
2. "apple+case+10+cover"
3. "apple+case+10++cover"
4. "+apple"
5. "iphone8+"
目前,我这样做是为了将+替换为空格,如下所示:
def normalizer(value: String): String = {
if (value == null) {
null
} else {
value.replaceAll("\\+", BLANK_SPACE)
}
}
val testUDF = udf(normalizer(_: String): String)
df.withColumn("newCol", testUDF($"value"))
但这将取代所有的“+”。如何替换字符串之间的“+”,同时处理诸如“apple+case+10++cover”=>“apple case 10+cover”之类的用例
您可以尝试替换两个正则表达式:
df.withColumn("newCol", regexp_replace(
regexp_replace(testUDF("value"), "(?<=\d)\+(?!\+)", "+ "),
"(?<!\d)\+", " ")).show
然后,外部正则表达式的替换对象是前面没有数字的所有加号,并用空格替换它们。示例,从上面继续:
apple+case+10+ cover --> apple case 10+ cover
您可以使用
regexp\u replace
而不是udf来执行此操作,它应该更快。在大多数情况下,您可以在regexp中使用负前瞻,但对于“+apple”,您实际上希望将“+”替换为“”(而不是空格)。最简单的方法是简单地使用regexp
df.withColumn("newCol", regexp_replace($"value", "^\\+", ""))
.withColumn("newCol", regexp_replace($"newCol", "\\+(?!\\+|$)", " "))
这将提供:
+--------------------+--------------------+
|value |newCol |
+--------------------+--------------------+
|apple+case |apple case |
|apple+case+10+cover |apple case 10 cover |
|apple+case+10++cover|apple case 10+ cover|
|+apple |apple |
|iphone8+ |iphone8+ |
+--------------------+--------------------+
为了使其更加模块化和可重用,您可以将其定义为一个函数:
def normalizer(c: String) = regexp_replace(regexp_replace(col(c), "^\\+", ""), "\\+(?!\\+|$)", " ")
df.withColumn("newCol", normalizer("value"))
这并不能取代“Apple + Case+ 10 +覆盖”和“Apple + Case+ 10 + +覆盖”-通过这一测试似乎只适用于单一的“+”,我认为“代码> Apple + Case+ 10 +覆盖< /代码>是坏数据。你真的有这些数据吗?是的。它是一个常见的用例。至少我希望++替换为单个“”(最坏情况解决方案)testUDF(“值”)应该已经替换字符串中的所有+,对吗?tat应该是外部的吗?@user3407267请检查更新的答案,它现在应该可以工作了。问题是我需要在多个DFs中应用这一点,这就是为什么认为UDF是更干净的方法。请让我知道,如果你有任何其他更干净,更快的方法,我可以应用于多个领域DFs@user3407267:如果您想,您只需将regexp放入您的UDF中,它仍然可以工作。但是您也可以在方法中使用
regexp\u replace
(保持速度),我在答案中添加了一些信息。
+--------------------+--------------------+
|value |newCol |
+--------------------+--------------------+
|apple+case |apple case |
|apple+case+10+cover |apple case 10 cover |
|apple+case+10++cover|apple case 10+ cover|
|+apple |apple |
|iphone8+ |iphone8+ |
+--------------------+--------------------+
def normalizer(c: String) = regexp_replace(regexp_replace(col(c), "^\\+", ""), "\\+(?!\\+|$)", " ")
df.withColumn("newCol", normalizer("value"))