过滤器的奇怪行为?

时间:2016-03-07 11:00:00

标签: regex scala

我想从多行字符串中提取类似MIME的标题(从[Cc] ontent-开始):

scala> val regex = "[Cc]ontent-".r
regex: scala.util.matching.Regex = [Cc]ontent-

scala> headerAndBody
res2: String =
"Content-Type:application/smil
Content-ID:0.smil
content-transfer-encoding:binary
<smil><head>
"

这失败

scala> headerAndBody.lines.filter(x => regex.pattern.matcher(x).matches).toList
res4: List[String] = List()

但“相关”案例按预期工作:

scala> headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList
res5: List[String] = List(Content-Type:application/smil, Content-ID:0.smil, content-transfer-encoding:binary, <smil><head>)

scala> headerAndBody.lines.filter(x => x.startsWith("Content-")).toList
res8: List[String] = List(Content-Type:application/smil, Content-ID:0.smil)

中我做错了什么
x => regex.pattern.matcher(x).matches

因为它返回一个空的List ??

2 个答案:

答案 0 :(得分:3)

第一行失败的原因是您使用需要完整字符串匹配的java.util.regex.Matcher.matches()方法。

要解决此问题,请使用 Matcher.find() 方法在输入字符串中的任意位置搜索匹配使用"^[Cc]ontent-"正则表达式(请注意^符号将强制匹配出现在字符串的开头。)

请注意,这行代码无法正常工作:

headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList

您对模式Content-运行正则表达式检查,并且它始终为true(这就是您获得结果中所有行的原因。)

请参阅this IDEONE demo

val headerAndBody = "Content-Type:application/smil\nContent-ID:0.smil\ncontent-transfer-encoding:binary\n<smil><head>"
val regex = "^[Cc]ontent-".r
val s1 = headerAndBody.lines.filter(x => regex.pattern.matcher(x).find()).toList
println(s1)
val s2 = headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList
print (s2)

结果(第一个是修复,第二个显示第二行代码失败):

List(Content-Type:application/smil, Content-ID:0.smil, content-transfer-encoding:binary)
List(Content-Type:application/smil, Content-ID:0.smil, content-transfer-encoding:binary, <smil><head>)

答案 1 :(得分:1)

你的正则表达式应匹配所有行,但不仅仅是第一个子串。

val regex = "[Cc]ontent-.*".r