我有一个test_list.txt文件,其中包含文件名行。每个文件名都包含创建日期。外观如下:
test_list.txt:
UTF_06012018_SAMPLE_Control.xlsx
UTF_06022018_SAMPLE_Control.xlsx
UTF_06092018_SAMPLE_Control.xlsx
UTF_06022018_SAMPLE_Control.xlsx
UTF_06082018_SAMPLE_Control.xlsx
UTF_06032018_SAMPLE_Demand.xlsx
UTF_06092018_SAMPLE_Demand.xlsx
UTF_06122018_SAMPLE_Demand.xlsx
UTF_06032018_SAMPLE_Control.xlsx
UTF_06022018_SAMPLE_Demand.xlsx
文件名中的日期格式为mmddyyyy。另外,有些文件是在同一日期创建的。我想做的是打印与日期的正则表达式匹配的行,并按日期的字母顺序对其进行排序。
到目前为止,这是我的代码:
path = Dir.glob('/path/to/my/file/*.txt').first
regex = /(\d{1,2}\d{1,2}\d{4})/
samplefile = File.open(path)
string = File.read(samplefile)
string.scan(regex).each do|x|
sorted = x.sort_by { |s| s.scan(/\d+/).first.to_i }
puts sorted
end
但是,我的代码所做的是它仅打印日期,而不打印整个行。除此之外,它甚至没有按字母顺序对它们进行排序。如何调整并使其按我的意愿进行?
答案 0 :(得分:1)
您可以使用
string.scan(/^([^_]*_(\d++)(.*))/).sort_by { |m,n,z| [n.to_i,z] }.collect{ |m,n,z| m}.join("\n")
请参见Ruby demo。
正则表达式会将所有行提取到具有以下值的三元素数组中:整行,日期字符串和日期之后的字符串。然后,.sort_by { |m,n,z| [n.to_i,z] }
将首先按日期字符串排序,然后按日期之后的子字符串排序。 .collect{ |m,n,z| m}
将仅保留数组元素的第一个值,而.join("\n")
将重新生成结果字符串。
请注意,您可能要先解析日期字符串,然后再使用[n.to_i,z]
(添加[Date.strptime(n,"%d%m%Y"),z]
),而不是require 'date'
。
正则表达式详细信息
^
-一行的开头([^_]*_(\d++)(.*))
-第1组(m
):整行符合以下模式:
[^_]*
-除_
之外的零个或多个字符_
-下划线(\d++)
-第2组(n
):1个以上的数字,所有格匹配(.*)
-第3组(z
):该行的其余部分。