#python #regex #parsing
#python #регулярное выражение #синтаксический анализ
Вопрос:
Я анализирую файл журнала, в котором есть строки типа:
Pushing the logs into /var/log/my_log.txt
Pushing the logs into /opt/test/log_file.txt
Существует несколько вхождений этих строк с автоматически сгенерированными путями (/…/…/…)
Я хочу изменить это в общую форму, например:
Pushing the logs into PATH
Я попытался использовать регулярное выражение для выбора слова с несколькими косыми чертами, а затем заменить его словом «ПУТЬ» следующим образом:
line = re.sub(r'b([/A-Z]*/[A-Z]*){1,}b',' PATH ',line)
Заменяются только косые черты, но не все слово.
Очень ново для этой концепции. Я делаю что-то не так? Любая помощь приветствуется. Спасибо.
Комментарии:
1. попробуйте,
re.sub("/.*", 'PATH', line)
Ответ №1:
Вы могли бы использовать:
import re
line = 'Pushing the logs into /var/log/my_log.txt'
pat = r'(?<!S)(/S ){2,}'
line = re.sub(pat, 'PATH', line)
print(line)
Это не отвечает точно так, как указано, потому что оно ищет «слова», которые должны начинаться с /
, а также содержать два или более /
(с другими символами, не содержащими пробелов после каждого /
) — так что это будет охватывать, например, /tmp/my_log.txt
. Я думаю, что это лучше охватывает вид строк, которые вы найдете — если они являются абсолютными путями, то /
всегда будет первым символом, и аналогично, если это файлы, а не каталоги, то последний /
не будет в конце ( хотя я не потрудился исключить a /
в конце при условии, что перед ним также есть по крайней мере два). Если вы хотите искать только, например, 3 или более /
(не в конце), то измените 2 на 3, но вы пропустите /tmp/my_log.txt
, если сделаете это.
Первый бит регулярного выражения (?<!S)
является отрицательным утверждением lookbehind, означающим «не предшествует символ без пробелов», то есть он будет соответствовать началу «слова» или началу строки. Следующий бит (/S )
означает /
, за которым следует один или несколько символов, не содержащих пробелов (которые могут включать /
— это не имеет значения, поэтому я не потрудился исключить их). И {2,}
означает, что их должно быть два или более.
(Я использую «word» здесь, как и в вопросе, для обозначения последовательности символов, не содержащих пробелов, не обязательно букв.)
Ответ №2:
Сопоставляются только прямые косые черты, потому что строка написана в нижнем регистре, а шаблон соответствует нулю или более раз либо косой черте, либо символу верхнего регистра от АдоЯ, используя [/A-Z]*
Вы могли бы сделать шаблон нечувствительным к регистру, используя re.IGNORECASE
но он не будет соответствовать подчеркиванию и точке в данных примера.
Первая косая черта не сопоставляется при запуске шаблона с границей слова b
, но между пробелом и первой косой чертой нет границы слова.
Немного более конкретное соответствие может быть использовано w
для сопоставления символа слова и указания точки для расширения:
(?<!S)(?:/w ) /w .w (?!S)
(?<!S)
Установите границу пробела слева(?:/w )
Сопоставьте 1 или более раз/
, за которыми следует 1 слово символов/w .w
Сопоставьте последнее/
, за которым следует формат имени файла, используя символы точки и слова(?!S)
Установите границу пробела справа
Смотрите демонстрация регулярных выражений | Демонстрация Python
import re
line = 'Pushing the logs into /var/log/my_log.txt'
line = re.sub(r'(?<!S)(?:/w ) /w .w (?!S)', 'PATH', line)
print(line)
Вывод
Pushing the logs into PATH
Более широкий шаблон может соответствовать 2-кратной косой черте и использовать класс отрицаемых символов для соответствия любому символу, кроме косой черты или новой строки
(?<!S)(?:/[^/rn] ){2,}
Смотрите другую демонстрацию регулярных выражений