我试图从scala中的字符串中删除重复的单词。
我写了一个udf(下面的代码)从字符串中删除重复的单词:
val de_duplicate: UserDefinedFunction = udf ((value: String) => {
if(value == "" | value == null){""}
else {value.split("\\s+").distinct.mkString(" ")}
})
我面临的问题是它也从字符串中删除了单个字符标记,
例如,如果字符串为:
"test abc abc 123 foo bar f f f"
我得到的输出是:
"test abc 123 foo bar f"
我要做的是仅删除重复的单词,而不删除单个字符, 我可以想到的一种解决方法是替换字符串中任何单个字符标记之间的空格,以使示例输入字符串变为:
"test abc abc 123 foo bar fff"
这将解决我的问题,我无法找出正确的正则表达式模式,但我相信可以使用捕获组或提前查找来完成。我在其他语言中也看过类似的问题,但无法弄清楚scala中的正则表达式模式。
任何帮助,将不胜感激!
答案 0 :(得分:5)
如果要删除输入字符串中单个字符之间的空格,则可以使用以下正则表达式:
println("test abc abc 123 foo bar f f f".replaceAll("(?<= \\w|^\\w|^) (?=\\w |\\w$|$)", ""));
输出:
test abc abc 123 foo bar fff
演示:https://regex101.com/r/tEKkeP/1
说明:
正则表达式:(?<= \w|^\w|^) (?=\w |\w$|$)
将通过正向超前/后向闭合匹配由一个单词字符包围的空格(最终在其后有空格,或行锚的开头/结尾)。
更多输入:
test abc abc 123 foo bar f f f
f boo
f boo
boo f
boo f f
too f
相关输出:
test abc abc 123 foo bar fff
f boo
f boo
boo f
boo ff
too f
答案 1 :(得分:2)
您可以使用此正则表达式来定位长度为两个或更多字符的字符串中存在的重复单词,并将其替换为空字符串以仅保留唯一单词,
\b(\w{2,})\b\s*(?=.*\1)
说明:
\b(\w{2,})\b
-选择一个至少包含两个字符的单词\s*
-该可选空格用于删除单词后的所有空格,因此不需要的空格就不会在那里(?=.*\1)
-这种积极向上的眼神是锁定重复单词的关键,并且如果字符串中存在相同的单词,则可以通过选择一个单词来发挥作用object Rextester extends App {
val s = "abc test abc abc 123 foo bar foo f sd foo f f abc"
println("Unique words only: " + s.replaceAll("\\b(\\w{2,})\\b\\s*(?=.*\\1)",""))
}
仅输出唯一词,
Unique words only: test 123 bar f sd foo f f abc
编辑:
由于您不想删除重复的单词,而只是想删除单个字符单词之间的一个或多个空格,因此可以使用此正则表达式,
(?<=^|\b\w) +(?=\w\b|$)
并使用空字符串将其删除,
标量代码
val s = "test abc abc 123 foo bar f f f"
println("Val: " + s.replaceAll("(?<=^|\\b\\w) +(?=\\w\\b|$)",""))
输出
Val: test abc abc 123 foo bar fff