Scala 2.11.8中string.matches正则匹配出现异常行为求助
解决Scala 2.11.8中
string.matches不符合预期的问题 嘿,我猜你遇到的大概率是Scala里string.matches()方法的一个常见坑——它要求正则表达式完全匹配整个字符串,而不是你可能以为的“只要字符串里包含匹配的内容就行”!这是很多开发者初次使用时会踩的坑,我结合你的场景给你拆解清楚:
核心问题:matches的完全匹配特性
Scala的String.matches()本质上调用的是Java的同名方法,它的逻辑是:只有当你的正则表达式能覆盖整个输入字符串时,才会返回true。举个例子:
- 如果你想匹配文件里的列表项(比如
- First Line item),要是你写了line.matches("- .+"),看起来没问题,但如果行尾有隐藏的空格、制表符,或者你误以为这个正则会匹配“包含-的行”,那结果就会不符合预期——比如像- First Line item(行首有空格)这样的行,就会匹配失败,因为正则要求字符串必须以-开头,且整个字符串都符合- .+的格式。
针对你的场景的解决方案
根据你的需求,分两种情况处理:
1. 需求:匹配包含某模式的行(比如找所有列表项)
如果你的目标是找出文件中所有符合- 开头的行,不要用matches,改用Scala的Regex类的查找方法更合适:
import scala.io.Source import scala.util.matching.Regex // 定义匹配列表项的正则 val listItemPattern: Regex = "- .+".r // 读取文件并过滤出匹配的行 val lines = Source.fromFile("file.txt").getLines().toList val validListItems = lines.filter { line => // 检查行中是否存在匹配的模式 listItemPattern.findFirstIn(line).isDefined } validListItems.foreach(println)
2. 需求:完全匹配某格式的行(比如匹配标题行)
如果你确实需要完全匹配某类行(比如全是#的标题分隔线),那可以继续用matches,但要确保正则覆盖整个字符串:
// 匹配全是#的行 val separatorLines = lines.filter(line => line.matches("#+"))
这里line.matches("#+")等价于line.matches("^#+$"),因为matches本身就隐含了开头和结尾的锚定。
调试小技巧
如果还是不确定为什么匹配失败,可以先打印出行的原始内容,用符号包裹起来,排查是否有隐藏的空白字符:
lines.foreach(line => println(s"|$line|"))
这样就能直观看到行首/行尾是否有空格、制表符或者其他看不见的字符,这些往往是匹配失败的元凶。
内容的提问来源于stack exchange,提问作者mrbrahman
相关产品推荐
相关产品推荐

