整列上的 Scala 正则表达式
Posted
技术标签:
【中文标题】整列上的 Scala 正则表达式【英文标题】:Scala regex on a whole column 【发布时间】:2022-01-22 02:13:17 【问题描述】:我有以下模式,我可以在 Python 中使用 pandas 进行解析,但很难将代码翻译成 Scala。
grade string_column
85 (str:ann smith,14)(str:frank chase,15)
86 (str:john foo,15)(str:al more,14)
在我使用的python中:
df.set_index('grade')['string_column']\
.str.extractall(r'\((str:[^,]+),(\d+)\)')\
.droplevel(1)
输出:
grade 0 1
85 str:ann smith 14
85 str:frank chase 15
86 str:john foo 15
86 str:al more 14
在 Scala 中,我尝试复制该方法,但失败了:
import scala.util.matching.Regex
val pattern = new Regex("((str:[^,]+),(\d+)\)")
val str = "(str:ann smith,14)(str:frank chase,15)"
println(pattern findAllIn(str)).mkString(","))
【问题讨论】:
【参考方案1】:代码有几点说明:
组有一个不匹配的括号,但应该转义该括号 反斜杠应该双转义 在println
中,您不必使用所有括号和点
findAllIn 返回一个 MatchIterator,循环它们会暴露一个匹配的字符串。用逗号连接那些匹配的字符串,在这种情况下会再次返回相同的字符串。
例如
import scala.util.matching.Regex
val pattern = new Regex("\\((str:[^,]+),(\\d+)\\)")
val str = "(str:ann smith,14)(str:frank chase,15)"
println(pattern findAllIn str mkString ",")
输出
(str:ann smith,14),(str:frank chase,15)
但是如果你想打印出第 1 组和第 2 组的值,你可以使用返回 Regex Matches 集合的findAllMatchIn:
import scala.util.matching.Regex
val pattern = new Regex("\\((str:[^,]+),(\\d+)\\)")
val str = "(str:ann smith,14)(str:frank chase,15)"
pattern findAllMatchIn str foreach(m =>
println(m.group(1))
println(m.group(2))
)
输出
str:ann smith
14
str:frank chase
15
【讨论】:
【参考方案2】:在 Python 中,Series.str.extractall
仅返回捕获的子字符串。在 Scala 中,如果您不查询其 matchData
属性,而 findAllIn
又包含 subgroups
属性,则 findAllIn
将返回匹配的值。
因此,要仅在 Scala 中获取捕获,您需要使用
val pattern = """\((str:[^,()]+),(\d+)\)""".r
val str = "(str:ann smith,14)(str:frank chase,15)"
(pattern findAllIn str).matchData foreach
m => println(m.subgroups.mkString(","))
输出:
str:ann smith,14
str:frank chase,15
请参阅Scala online demo。
在这里,m.subgroups
访问每个匹配 (m
) 的所有子组(捕获)。
另外,请注意您不需要在三引号字符串文字中使用双反斜杠。 \((str:[^,()]+),(\d+)\)
匹配
\(
- 一个 (
字符
(str:[^,()]+)
- 第 1 组:str:
和一个或多个除 ,
、(
和 )
之外的字符
,
- 逗号
(\d+)
- 第 2 组:一位或多位数字
\)
- 一个 )
字符。
如果您只想获取所有匹配项而不捕获,您可以使用
val pattern = """\((str:[^,]+),(\d+)\)""".r
println((pattern findAllIn str).matchData.mkString(","))
输出:
(str:ann smith,14),(str:frank chase,15)
请参阅online demo。
【讨论】:
谢谢。我需要如何调整代码以在新数据帧(如 pandas)中获取输出?以上是关于整列上的 Scala 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章