0

在我的 PHP 脚本中,我从数据库字段中提取文件名列表。字段中的名称由逗号分隔,可以是各种长度,包含各种字符和/或空格。字符串可能如下所示:

“fileone.wav,文件二有空格.mp3,另一个文件,但这个有逗号,当然,问题.mp3,another_one.mp3”

我正在使用它来将它们分解成一个数组($attachments 包含来自 db 字段的字符串):

$filenames = explode(", ", $attachments);

我的 dliemma 是有时文件名包含逗号,因此爆炸失败,因为它在逗号处分隔名称。它当然会将文件名分解为单独的数组元素。

我想知道 preg_split 是否可能是匹配和拆分文件名的更好方法。我对正则表达式非常缺乏经验,但从概念上讲,我想我会通过匹配“。”来拆分名称,后面的三个字符,无论它们是什么和逗号。

这是一个好方法吗?我将如何写这个表达式?

4

2 回答 2

1

如果您的文件名中可以​​包含逗号(并且没有转义字符),则无法决定如何正确拆分文件名。

也许你有一个名为one.mp3,two.mp3. 决定像这样存储文件名的人犯了一个可怕的错误。有这么多可用的序列化程序,没有理由不使用任何一个。即使是类似的东西(un)serialize($attachments)也足够了。

您可以进行简单的检测,例如查找扩展名(.后跟某些内容),然后在第一个逗号处拆分。您不需要正则表达式,只需遍历字符串即可。

于 2013-05-13T15:26:21.327 回答
1

正如您所发现的,您拥有的数据格式存在根本缺陷。

理想情况下,您需要修复数据。如果你想坚持你的基本格式(即逗号分隔),你应该确保它以有效的 CSV 格式保存——即在包含逗号的值周围加上引号,所以你的字符串看起来像这样:

fileone.wav, file two with spaces.mp3, "another file but this one has commas, which is, of course, the problem.mp3", another_one.mp3

使用这种格式的数据,您可以使用 PHP 的内置 CSV 处理函数str_getcsv()来读取数据,而不是explode(). 问题解决了。

如果您乐于尝试其他格式,您还可以将数据重新格式化为 JSON 或其他序列化格式,这也将使事情更易于管理。

技术上最正确的答案仍然是规范化数据库,以便文件名有自己的表,并且每个表都在单独的记录中,但这对于您的目的来说可能是过度杀伤和/或太大的动荡。

所以是的,理想情况下你应该修复数据,因为它的格式设计得很糟糕。

但是,如果您真的无法修复数据,那么您将不得不求助于一些巧妙的正则表达式技巧来拆分文件。

假设所有文件都以“.mp3”结尾,则比较简单;你可以这样做:

preg_split(".mp3(,|$)",$data)

...这将为您提供不带.mp3扩展名的文件名。如果它们都是 mp3,那么很容易重新添加它。

如果您的文件名是混合文件类型,那么它会变得更加复杂;您需要使用正则表达式前瞻来查找扩展名,但不删除它们。

但是,您对所有这些的问题是文件名可能包含.mp3,在名称中间的某个位置。当然不可能,但有可能,特别是如果您允许您的用户上传他们自己的文件名。

于 2013-05-13T15:59:18.347 回答