Regex 过滤器的奇怪行为?

Regex 过滤器的奇怪行为?,regex,scala,Regex,Scala,我想从多行字符串中提取类似MIME的标题(以[Cc]content-”开头): 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 <

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

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("Content-").matches).toList
res5: List[String] = List(Content-Type:application/smil, Content-ID:0.smil, content-transfer-encoding:binary, <smil><head>)
我在这方面做错了什么

x => regex.pattern.matcher(x).matches

因为它返回一个空列表,所以regexp应该匹配所有行,而不仅仅是第一个子字符串


val regex=“[Cc]content-.*.r

您的regexp应该匹配所有行,而不仅仅是第一个子字符串


val regex=“[Cc]content-.*.r

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

要解决此问题,请使用
Matcher.find()
方法在输入字符串中的任何位置搜索匹配项,并使用
“^[Cc]内容-”
regex
(请注意,
^
符号将强制匹配项出现在字符串的开头)

请注意,这行代码的工作方式与预期不同:

headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList
根据模式
Content-
运行正则表达式检查,结果总是正确的(这就是为什么会得到结果中的所有行)

见:

val headerAndBody=“内容类型:应用程序/smil\n内容ID:0。smil\n内容传输编码:二进制\n”
val regex=“^[Cc]内容-”.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
打印(s2)
结果(第一个是修复,第二个显示第二行代码失败):

列表(内容类型:应用程序/smil,内容ID:0.smil,内容传输编码:二进制)
列表(内容类型:应用程序/smil,内容ID:0.smil,内容传输编码:二进制,)

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

要解决此问题,请使用
Matcher.find()
方法在输入字符串中的任何位置搜索匹配项,并使用
“^[Cc]内容-”
regex
(请注意,
^
符号将强制匹配项出现在字符串的开头)

请注意,这行代码的工作方式与预期不同:

headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList
根据模式
Content-
运行正则表达式检查,结果总是正确的(这就是为什么会得到结果中的所有行)

见:

val headerAndBody=“内容类型:应用程序/smil\n内容ID:0。smil\n内容传输编码:二进制\n”
val regex=“^[Cc]内容-”.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
打印(s2)
结果(第一个是修复,第二个显示第二行代码失败):

列表(内容类型:应用程序/smil,内容ID:0.smil,内容传输编码:二进制)
列表(内容类型:应用程序/smil,内容ID:0.smil,内容传输编码:二进制,)

很抱歉造成混淆:带有StartWith的部分确实按预期工作,显然它产生了一个无用的结果,这只是为了排除在使用filter时出现的任何错误()对不起,我的意思是
headerAndBody.lines.filter(x=>regex.pattern.matcher(“Content-”).matches)。toList
。我写的都是这一行,很抱歉复制/粘贴错误。不过,我在演示中使用了正确的代码行。find()的问题是它可能也会匹配正文中的内容,例如,如果正文是:-foo content bar-或其他内容,如果只需要匹配字符串的开头,则需要使用
“^[Cc]content-”。r
regex。插入符号将把匹配项锚定到字符串的开头。我根据最新的编辑更新了答案。很抱歉造成混淆:带有StartWith的部分确实按照预期工作,它产生了一个毫无用处的结果。显然,这只是为了排除使用过滤器时的任何错误()对不起,我的意思是
headerAndBody.lines.filter(x=>regex.pattern.matcher(“Content-”.matches”).toList
。我写的都是这一行,很抱歉复制/粘贴错误。不过,我在演示中使用了正确的代码行。find()的问题是它可能也会匹配正文中的内容,例如,如果正文是:-foo content bar-或其他内容,如果只需要匹配字符串的开头,则需要使用
“^[Cc]content-”。r
regex。插入符号将把匹配项锚定到字符串的开头。我根据最新编辑更新了答案。
headerAndBody.lines.filter(x => regex.pattern.matcher("Content-").matches).toList
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>)