过滤路径和文件名中的特殊字符

工作中碰到的一个问题.

控件的标签对应的是文件名, 如何有效过滤用户输入的内容, 以保证文件名符合规则呢?

.NET平台果然够强大, 拥有两个静态方法, 分别代表在路径和文件名里禁止使用的字符数组. Path.GetInvalidPathChars() Path.GetInvalidFileNameChars()

之后我第一个想到的是字符串的Replace()方法: "123#4".Replace("#", "")

可是对于Replace(oldChar, newChar)这种重载的使用, 却碰到了一些问题.str.Replace(\'#\', \'\') str.Replace(\'#\', Char.MinValue) 两个都不行.

那就把字符数组转换成字符串数组吧

1
2
3
4
5
6
7
8
9
let cleanFileName str =
let rec repeat (s :string) invalidCharList =
match invalidCharList with
| h :: t -> repeat (s.Replace(h, "")) t
| [] -> s
Path.GetInvalidFileNameChars()
|> List.of_array
|> List.map (fun x -> x.ToString())
|> repeat str

虽然说问题能够得到解决, 但总觉得有点缺憾, 接下来我想到了String.Split()方法, 此方法不正是需要Char[]这样的参数么?

1
2
3
4
5
6
7
8
9
10
let cleanFileName (str :string) =
let join s = String.Join("", s)
Path.GetInvalidFileNameChars() // 使用特殊字符数组
|> str.Split // 把字符串拆分开来
|> join // 然后连接在一起
// 哈~ 汉编如果能做到这样, 会有很多人认同的.

// 要是连可读性都不要了, 也可以写成这样:
let cleanFileName (str :string) =
String.Join("", str.Split(Path.GetInvalidFileNameChars()))