我目前正在编写一个函数,使用UNIX ls -m
命令列出一堆文件,然后使用正则表达式将它们转换为列表。
我的功能如下:
def genFileList(path : String = "~") : Iterator[String] = {
val fileSeparatorRegex: Regex = "(.*),".r
val fullCommand : String = s"ls -m $path"
val rawFileList: String = fullCommand.!!
val files: Iterator[String] = fileSeparatorRegex.findAllIn(rawFileList).matchData.map(_.group(1))
var debug : List[String] = files.toList
debug
files
}
例如:假设我有一个名为test的文件夹,包含3个文件:test.txt test1.txt test2.txt。结果列表是:
很奇怪......
让我们将功能更改为:
def genFileList(path : String = "~") : Iterator[String] = {
val fileSeparatorRegex: Regex = "(.*)\\n".r \\ Changed to match newline
val fullCommand : String = s"ls -1 $path" \\ Changed to give file name separated via newline
val rawFileList: String = fullCommand.!!
val files: Iterator[String] = fileSeparatorRegex.findAllIn(rawFileList).matchData.map(_.group(1))
var debug : List[String] = files.toList
debug
files
}
Tadaaaa:
任何人都可以帮助我理解第一个失败的案例吗?
为什么ls -m
生成的逗号不匹配?
答案 0 :(得分:5)
(.*)
是一种贪婪的模式,它会尝试尽可能多地匹配,包括逗号
test1.txt, test2.txt, test3.txt
^------------------^^
all of this is |
matched by .* this is matched by ,
最后一个块不匹配,因为它后面没有逗号。
您可以使用.*?
或者,你可以只做rawFileList.stripSuffix("\n").split(", ").toList
此外,"ls -m ~".!!
不起作用,如果文件名包含逗号,“s"ls -m $path".!!
要求shell注入,并且new File(path).list()
更好”,则在逗号上拆分输出将不起作用各方面。
答案 1 :(得分:0)
我可以看到您的初始方法存在两个问题。首先是你的正则表达式中的*
是贪婪的,这意味着它在达到逗号(包括其他逗号)之前尽可能地吮吸。如果您通过添加?
(即"(.*?),".r
)将其更改为非贪婪,则只会匹配第一个逗号。
第二个问题是最后一个文件后面没有逗号(自然地),因此正则表达式找不到它。在您的第二种方法中,您将获得所有三个文件,因为每个文件后面都有换行符。如果你想坚持使用逗号,最好使用split
(例如rawFileList.split(",")
)。
您还可以考虑在list
上使用listFiles
或java.io.File
方法:
scala> val dir = new java.io.File(".")
f: java.io.File = .
scala> dir.list
res0: Array[String] = Array(test, test1.txt, test2.txt)