整个列上的 Scala 正则表达式
Scala regex on a whole column
我可以使用 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(","))
关于代码有几点说明:
- 组中有一个不匹配的括号,但应转义该括号
- 反斜杠应该双重转义
- 在
println
中,您不必使用所有括号和点
- findAllIn returns 一个 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 组的值,你可以使用 findAllMatchIn 那个 returns 正则表达式匹配的集合:
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
在Python中,Series.str.extractall
仅returns捕获子字符串。在 Scala 中,findAllIn
returns 匹配的值如果你不查询它的 matchData
属性 而它又包含一个 subgroups
属性.
因此,要仅在 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
此处,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。
我可以使用 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(","))
关于代码有几点说明:
- 组中有一个不匹配的括号,但应转义该括号
- 反斜杠应该双重转义
- 在
println
中,您不必使用所有括号和点 - findAllIn returns 一个 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 组的值,你可以使用 findAllMatchIn 那个 returns 正则表达式匹配的集合:
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
在Python中,Series.str.extractall
仅returns捕获子字符串。在 Scala 中,findAllIn
returns 匹配的值如果你不查询它的 matchData
属性 而它又包含一个 subgroups
属性.
因此,要仅在 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
此处,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。