Regex для замены путей к файлам в строке, если в Python их больше одного - PullRequest
0 голосов
/ 07 февраля 2020

У меня проблемы с поиском способа сопоставления нескольких путей к файлам в строке при сохранении оставшейся части строки.

РЕДАКТИРОВАТЬ: забыл добавить, что путь к файлу может содержать точку , поэтому отредактировал "username" в user.name "

# filepath always starts with "file:///" and ends with file extension
text = """this is an example text extracted from file:///c:/users/user.name/download/temp/anecdote.pdf 
1 of 4 page and I also continue with more text from 
another path file:///c:/windows/system32/now with space in name/file (1232).html running out of text to write."""

Я нашел много ответов, которые работают, , но не удается, когда существует более одного пути к файлу , также заменяя другие символы в между.

import re
fp_pattern = r"file:\/\/\/(\w|\W){1,255}\.[\w]{3,4}"
print(re.sub(fp_pattern, "*IGOTREPLACED*", text, flags=re.MULTILINE))

>>>"this is an example text extracted from *IGOTREPLACED* running out of text to write."

Я также пытался использовать «Стоп, когда после нахождения пробела после шаблона», но я не мог заставить его работать:

fp_pattern = r"file:\/\/\/(\w|\W){1,255}\.[\w]{3,4} ([^\s]+)"
>>> 0 matches

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Обратите внимание, что {1,255} является жадным квантификатором и будет соответствовать как можно большему числу символов, вам необходимо добавить ? после него.

Однако, просто используя ленивый {1,255}? выигранный квантификатор ' решить проблему. Вам нужно определить, где должен закончиться матч. Похоже, вы хотите сопоставлять эти URL-адреса только тогда, когда за расширением сразу следует пробел или конец строки.

Следовательно, используйте

fp_pattern = r"file:///.{1,255}?\.\w{3,4}(?!\S)"

См. Демонстрационную версию regex

Отрицательный запрос (?!\S) провалит любое совпадение, если непосредственно справа от текущего местоположения есть непробельный символ. .{1,255}? будет соответствовать любому от 1 до 255 символов, как можно меньше.

Использовать в Python как

re.sub(fp_pattern, "*IGOTREPLACED*", text, flags=re.S)

Флаг re.MULTILINE (re.M) только переопределяет поведение привязки ^ и $, делая их соответствующими началу / концу строк , а не вся строка. Флаг re.S позволяет . соответствовать любым символам, включая символы разрыва строки.

Пожалуйста, никогда не используйте (\w|\W){1,255}?, используйте .{1,255}? с флагом re.S, чтобы соответствовать любому символу, иначе производительность будет убывать.

0 голосов
/ 07 февраля 2020

Вы можете попробовать re.findall, чтобы узнать, сколько регулярных выражений совпадает в строке. Надеюсь, это поможет.

import re
len(re.findall(pattern, string_to_search))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...