在我的PHP脚本中,我从数据库字段中提取文件名列表。字段中的名称用逗号分隔,可以是包含各种字符和/或空格的各种长度。字符串看起来像这样:
“fileone.wav,文件二与spaces.mp3,另一个文件,但这一个有逗号,当然,这是problem.mp3,another_one.mp3”
我使用它将它们分解为一个数组($ attachments包含db字段中的字符串):
$filenames = explode(", ", $attachments);
我的理由是,有时文件名包含逗号,因此爆炸失败,因为它用逗号分隔名称。它当然会将文件名分成单独的数组元素。
我想知道preg_split是否是匹配和拆分文件名的更好方法。我对正则表达式非常缺乏经验,但从概念上讲,我想通过匹配“。”,后面跟随的三个字符,无论它们是什么和逗号来分割名称。
这是一个很好的方法吗?我该怎么写这个表达?
答案 0 :(得分:1)
如果您的文件名中可以包含逗号(并且没有转义字符),则无法确定如何正确拆分文件名。
也许您有一个名为one.mp3,two.mp3
的文件。决定存储这样的文件名的人犯了一个可怕的错误。有这么多序列号可用,没有理由不使用任何。即使像(un)serialize($attachments)
这样的东西就足够了。
您可以执行简单检测,例如查找扩展名(.
后跟某些内容),然后在第一个逗号处拆分。你不需要正则表达式,只需走一下字符串。
答案 1 :(得分: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,
。当然不太可能,但可能,特别是如果您允许用户上传自己的文件名。