用于匹配日期时间后跟空格和任何字符的正则表达式

RegEx for matching a datetime followed by spaces and any chars

我需要分析存储桶中的一些数据,遇到了一些难题。 这是每个文件中的行类型:

"2018-09-08 10:34:49 10.0 MiB path/of/a/directory"

需要的是用粗体捕获所有内容,同时记住一些分隔符是制表符,而其他时候它们是 spaces。

换句话说,我需要从日期和时间结束那一刻起的所有内容(不包括制表符或它前面的 space)

我试过这样的事情:

p = re.compile(r'^[\d\d\d\d.\d\d.\d\d\s\d\d:\d\d:\d\d].*')
for line in lines:
    print(re.findall(line))

如何解决这个问题?

编辑: 如果我还想在新匹配的字符串中创建新组怎么办?说我想重新创建它 --> 10MiB engagementName/folder/file/something.xlsx engagementName extensionType something.xlsx

重新编辑: path/to/directory 通常指向一个文件(所有文件都有扩展名)。从你们一直在帮助我的重新格式化的字符串中,有没有一种方法可以继续构建正则表达式模式,允许我通过对 fileExtensionType 的过滤来 "create" 一个新组(我想通过搜索.anything) 的字符串,并将该结果添加到格式化的正则表达式字符串中?

不要为正则表达式而烦恼。您知道该行的格式。拆分一下:

from datetime import datetime

for l in lines:
    line_date, line_time, rest_of_line = l.split(maxsplit=2)
    print([line_date, line_time, rest_of_line])
    # ['2018-09-08', '10:34:49', '10.0 MiB path/of/a/directory']

请特别注意 maxsplit 参数的使用。这可以防止它拆分大小或路径。我们可以这样做,因为我们知道日期中间有一个 space,后面有一个 space。

如果尺寸总是中间有一个 space,后面有一个 space,我们也可以将其增加到 4 个拆分来分隔尺寸:

for l in lines:
    line_date, line_time, size_quantity, size_units, line_path = l.split(maxsplit=4)
    print([line_date, line_time, size_quantity, size_units, line_path])
    # ['2018-09-08', '10:34:49', '10.0', 'MiB', 'path/of/a/directory']

请注意,路径中多余的连续 space 和 space 不会搞砸:

l = "2018-09-08 10:34:49     10.0   MiB    path/of/a/direct       ory"
line_date, line_time, size_quantity, size_units, line_path = l.split(maxsplit=4)
print([line_date, line_time, size_quantity, size_units, line_path])
# ['2018-09-08', '10:34:49', '10.0', 'MiB', 'path/of/a/direct       ory']

如果需要,您可以将各部分重新连接在一起:

line_size = size_quantity + ' ' + size_units


如果你想要某物的时间戳,你可以解析它:

# 'T' could be anything, but 'T' is standard for the ISO 8601 format
timestamp = datetime.strptime(line_date + 'T' + line_time, '%Y-%m-%dT%H:%M:%S')

您可能不需要表达式来执行此操作,字符串拆分就足够了。但是,如果您希望这样做,您可能不想从一开始就限制您的表达。您可以简单地使用 this expression:

(:[0-9]+\s+)(.*)$ 

您甚至可以将其稍微修改为 this expression,这样会快一点:

:([0-9]+\s+)(.*)$

图表

图表显示了表达式的工作原理:


示例测试:

# -*- coding: UTF-8 -*-
import re

string = "2018-09-08 10:34:49   10.0 MiB path/of/a/directory"
expression = r'(:[0-9]+\s+)(.*)$'
match = re.search(expression, string)
if match:
    print("YAAAY! \"" + match.group(2) + "\" is a match  ")
else: 
    print(' Sorry! No matches! Something is not right! Call 911 ')

输出

YAAAY! "10.0 MiB path/of/a/directory" is a match  

JavaScript 性能基准

此代码段是 JavaScript 性能测试,输入字符串重复 1000 万次:

repeat = 10000000;
start = Date.now();

for (var i = repeat; i >= 0; i--) {
 var string = "2018-09-08 10:34:49  10.0 MiB path/of/a/directory";
 var regex = /(.*)(:[0-9]+\s+)(.*)/g;
 var match = string.replace(regex, "");
}

end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");

编辑:

你可能只捕获时间戳的结尾,因为你的表达式边界更少,它变得简单和更快,如果出现意外情况,它仍然有效:

2019/12/15 10:00:00     **desired output**
2019-12-15    10:00:00     **desired output**
2019-12-15, 10:00:00     **desired output**
2019-12 15 10:00:00     **desired output**