RegEx для сопоставления даты и времени с пробелами и любыми символами - PullRequest
3 голосов
/ 06 мая 2019

Мне нужно профилировать некоторые данные в ведре, и я столкнулся с некоторой дилеммой.Это тип строки в каждом файле:

"2018-09-08 10:34:49 10,0 МБ / путь / из / a / directory "

Чтотребуется, чтобы все было выделено жирным шрифтом, при этом следует помнить, что некоторые из разделителей являются символами табуляции, а другие - пробелами.пробел перед ним)

Я пробовал что-то вроде этого:

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 / папка / файл / что-то. Xlsx расширениеNameName ExtensionType что-то.Каталог / обычно указывает на файл (и все файлы имеют расширения).из переформатированной строки, с которой вы, ребята, мне помогли, есть ли способ продолжить построение шаблона регулярного выражения, чтобы я мог «создать» новую группу с помощью фильтрации по fileExtensionType (я полагаю, что поиск в конце строки приводит кчто-то вроде строк .anything) и добавление этого результата в отформатированную строку регулярного выражения?

Ответы [ 2 ]

4 голосов
/ 06 мая 2019

Не беспокойтесь регулярным выражением.Вы знаете формат строки.Просто разделите его:

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.Это предотвращает расщепление по размеру или пути.Мы можем сделать это, потому что мы знаем, что дата имеет один пробел в середине и один пробел после нее.

Если размер всегда будет иметь один пробел в середине и один пробел после него, мы можем увеличить его до 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']

Обратите внимание, что дополнительные смежные пробелы и пробелы в пути не запутывают его:

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')
1 голос
/ 06 мая 2019

Для этого может не потребоваться выражение, достаточно разделения строки.Однако, если вы хотите сделать это, вы можете не захотеть ограничивать свое выражение с самого начала.Вы можете просто использовать это выражение :

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

Вы можете даже слегка изменить его на это выражение , что немного быстрее:

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

enter image description here

График

График показывает, как работает выражение:

enter image description here


Пример теста:

# -*- 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 с 10миллион раз повторения введенной вами строки:

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, "$3");
}

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**
...