Как найти и заменить фрагменты URI на Regex в Python? - PullRequest
0 голосов
/ 27 января 2020

Привет!

Я пытаюсь найти и заменить фрагменты URI в текстовом файле, но я просто не знаю, как это можно сделать.

Некоторые ресурсы начинаются с URL (например, http://www.example.com/{fragment}), другие начинаются с определенного префикса (например, example:{fragment}). Оба фрагмента представляют один и тот же объект, поэтому любые изменения в одном вхождении должны быть сделаны для всех вхождений фрагментов с префиксом и URL и наоборот.

Вот пример:

Каждый раз http://www.example.com/Example_1 или Появляется example:Example_1 Я хочу заменить все вхождения фрагмента Example_1 в файле на UUID (например, 186e4707_afc8_4d0d_8c56_26e595eba8f0), в результате чего все вхождения будут заменены либо http://www.example.com/186e4707_afc8_4d0d_8c56_26e595eba8f0, либо example:186e4707_afc8_4d0d_8c56_26e595eba8f0.

Это должно происходить для каждого уникального фрагмента в файле, это означает, что для Example_2, Example_3 и т. Д. Используется другой UUID.

До сих пор мне удалось обнаружить, что эта строка Regex: (((?<=### http:\/\/archive\.semantyk\.com\/).*)|(?<=archive:)([^\s]+)) работает для идентификации фрагментов, но я действительно застрял с заменяющей частью.

Я считаю, что это не сложная проблема, но я признаю, что это сложность.

Я надеюсь, что объяснил себя достаточно хорошо, но в случае, если я не смог, пожалуйста, дайте мне знать.

Знаете ли вы, как это можно решить ??

Большое вам спасибо за чтение этого далеко вместе. * 103 4 *


РЕДАКТИРОВАТЬ:

Я попытался использовать re.sub с использованием этого ввода:

###  http://archive.semantyk.com/Abbreviation
archive:Abbreviation rdf:type owl:Class ;
                     rdfs:subClassOf archive:Word .


###  http://archive.semantyk.com/Ability
archive:Ability rdf:type owl:Class ;
                rdfs:subClassOf archive:Quality .

, и он дает такой результат:

###  http://archive.semantyk.com/4f5b99bb_2bff_4166_8468_0134a1d864ae
archive:4f5b99bb_2bff_4166_8468_0134a1d864ae rdf:type owl:Class ;
                     rdfs:subClassOf archive:4f5b99bb_2bff_4166_8468_0134a1d864ae .


###  http://archive.semantyk.com/4f5b99bb_2bff_4166_8468_0134a1d864ae
archive:4f5b99bb_2bff_4166_8468_0134a1d864ae rdf:type owl:Class ;
                rdfs:subClassOf archive:4f5b99bb_2bff_4166_8468_0134a1d864ae .

Но это неверно, поскольку UUID одинаков, но ресурсы (фрагменты) не совпадают.

Есть идеи?


РЕДАКТИРОВАТЬ: РЕШЕНО!

Код xcan решен Это! Я только что сделал некоторые настройки, чтобы он работал.

Вот окончательный код:

import re
import uuid

def generateUUID():
    identifier = uuid.uuid4().hex
    identifier = identifier[0:8] + '_' + identifier[8:12] + '_' + identifier[12:16] + '_' + identifier[16:20] + '_' + identifier[20:]
    print('Generated UUID: ' + identifier)
    return identifier

def main():
    text = open('{path}', 'r').read()
    # Firsts find what needs to changed.
    rg = r"archive:([^\s]+)"
    matches = re.findall(rg, text, re.M)
    # convert list to a set to get rid of repeating matches
    # then convert back to a list again
    unique_matches = list(set(matches))

    # Change unique words with unique uuids. Same word won't get a
    # different uuid
    for match in unique_matches:
        pattern = r"(?<=archive:)(" + match + ")"
        text = re.sub(pattern, str(generateUUID()), text)

    file = open('{path}', 'w')
    file.write(text)
    file.close()

main()

Вам просто нужно заменить {путь} на путь к вашему файлу и все! Надеюсь, что это работает и для вас.

Ура!

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Вы можете передать функцию в re.sub с аргументом repl, как показано здесь . Таким образом, вы можете обрабатывать каждый матч с вашим собственным набором правил.

РЕДАКТИРОВАТЬ

Отредактировано в соответствии с комментариями. archive:.. совпадений найдено, затем заменено одно за другим, поэтому одинаковые совпадения, находящиеся где-то в другом месте в файле, получат одинаковый uuid.

import uuid
import re


def main():
    text = """  ###  http://archive.semantyk.com/Abbreviation
archive:Abbreviation rdf:type owl:Class ;
                    rdfs:subClassOf archive:Word .
###  http://archive.semantyk.com/Ability
archive:Ability rdf:type owl:Class ;
            rdfs:subClassOf archive:Quality .
                ###  http://archive.semantyk.com/Abbreviation
archive:Abbreviation rdf:type owl:Class ;
                    rdfs:subClassOf archive:Word ."""

    # Firsts find what needs to changed.
    rg = r"archive:([^\s]+)"
    matches = re.findall(rg, text, re.M)
    # convert list to a set to get rid of repeating matches
    # then convert back to a list again
    unique_matches = list(set(matches))

    # Change unique matches with unique uuids. Same matches won't get a
    # different uuid
    for match in unique_matches:
        pattern = r"(?<=archive:)(" + match + ")"
        text = re.sub(pattern, str(uuid.uuid4()), text)

    print(text)


if __name__ == "__main__":
    main()
0 голосов
/ 27 января 2020

Вы можете использовать модуль re (regex) для замены подходящего шаблона, давайте посмотрим:

import re
re.sub(pattern, repl, string, count=0, flags=0)
...