我在Delphi7中遇到了问题。我的应用程序根据设定的命名惯例创建mpg视频文件,即
\ 000_A_Title_YYYY-MM-DD_HH毫米ss_Index.mpg
在此文件名中,强制执行以下规则:
000
是视频序列。只要用户按下停止,它就会递增。
A
(或B,C,D)指定录制摄像机 - 因此视频文件最多可同时播放四个视频流。
Title
是一个可变长度的字符串。在我的应用程序中,它不能包含_
。
YYYY-MM-DD_HH-mm-ss
是视频序列的开始时间(不是单个文件)
Index
是基于零的排序索引,并在1个视频序列中递增。也就是说,视频文件最长可达15分钟,一旦达到此目的,新的视频文件将以相同的序列号启动,但下一个索引。使用此,我们可以计算文件(Filename decoded time + 15*Index)
使用此方法,我的应用程序可以提取视频文件开始录制的开始时间。
现在我们还需要处理任意命名的视频文件。我唯一知道的是文件名中会有一个YYYY-MM-DD HH-mm-ss。
如何让用户为他导入的文件指定文件名约定?像正则表达式?我知道命名方案必须有一个模式。
因此,如果用户在文本框中输入?_(Camera)_*_YYYY-MM-DD_HH-mm-ss_(Index).mpg
,我将如何获取开始时间?有更好的解决方案吗?或者,当我们遇到它们时,我是否只需处理每一种可能性?
(我知道这可能不是解决此类问题的最佳方法,但我们无法更改问题 - 新视频文件由其他公司录制)
答案 0 :(得分:4)
我不确定您是否尝试将用户输入解析为组件'?(相机) * _ YYYY-MM-DD_HH-mm-ss_(索引).mpg`但是如果你刚才试图抓住这样的日期和时间,日期在第1组,第2组的时间
(\d{4}-\d{2}-\d{2})_(d{2}-\d{2}-\d{2})
否则,不确定你要做什么。
答案 1 :(得分:3)
可能你可以使用下划线“_”作为你的位置指示器,因为你明智地不允许它们出现在标题中。
在您的文件名约定示例中:
?_(Camera)_*_YYYY-MM-DD_HH-mm-ss_(Index).mpg
你可以解析这个用户指定的字符串,看日期YYYY-MM-DD总是在第3和第4下划线之间,时间HH-mm-ss在第4和第5之间。
然后在获得遵循此约定的实际文件名时,找到第3个下划线并知道其后的日期和时间就变得很简单。
答案 2 :(得分:1)
如果你想全天候拨打电话,那么你应该选择RegEx-thing并让用户在TEdit中自由输入一些加密。
如果你想要快乐的用户和良好的睡眠,那么要有创意并放弃枯燥的RegEx方法。使用愤怒的小鸟方法创建自己的文件名解码器。
以下是这个想法:
示例代码:
program AngryBirdFilenameDecoder;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure PerformEatUntilDash(var aStr: String);
begin
if Pos('-', aStr) > 0 then
Delete(aStr, 1, Pos('-', aStr));
WriteLn(':-{ > ' + aStr);
end;
procedure PerformEatUntilUnderscore(var aStr: String);
begin
if Pos('_', aStr) > 0 then
Delete(aStr, 1, Pos('_', aStr));
WriteLn(':-/ > ' + aStr);
end;
function FetchDate(var aStr: String): String;
begin
Result := Copy(aStr, 1, 10);
Delete(aStr, 1, 10);
WriteLn(':-) > ' + aStr);
end;
var
i: Integer;
FileName: String;
TempFileName: String;
SelectedBirds: String;
MyDate: String;
begin
Write('Enter a filename to decode (eg. ''01-ThisIsAText-Img_01-Date_2011-03-08.png''): ');
ReadLn(FileName);
if FileName = '' then
FileName := '01-ThisIsAText-Img_01-Date_2011-03-08.png';
repeat
TempFileName := FileName;
WriteLn('Now, select some birds:');
WriteLn('Bird No.1 :-{ ==> I''ll eat letters until I find a dash (-)');
WriteLn('Bird No.2 :-/ ==> I''ll eat letters until I find a underscore (_)');
WriteLn('Bird No.3 :-) ==> I''ll remember the date before I eat it');
WriteLn;
Write('Chose your birds: (eg. 112123):');
ReadLn(SelectedBirds);
if SelectedBirds = '' then
SelectedBirds := '112123';
for i := 1 to Length(SelectedBirds) do
case SelectedBirds[i] of
'1': PerformEatUntilDash(TempFileName);
'2': PerformEatUntilUnderscore(TempFileName);
'3': MyDate := FetchDate(TempFileName);
end;
WriteLn('Bird No.3 found this date: ' + MyDate);
WriteLn;
WriteLn;
Write('Check filename with some other birds? (Y/N): ');
ReadLn(SelectedBirds);
until (Length(SelectedBirds)=0) or (Uppercase(SelectedBirds[1])<>'Y');
end.
当您使用GUI在Delphi中执行此操作时,您将添加更多鸟类并进行更多检查。并找到一些漂亮的鸟形象。
使用两个列表框。左边一个是所有可能的鸟类,右边一个是所有选定的鸟类。从左到右拖动鸟儿。重新排列(并删除)右侧列表中的鸟类。
用户应该能够通过输入文件名来测试设置并查看过程的结果。在内部,您可以使用枚举器等存储脚本。