Как скопировать найденные регулярные выражения из одного файла в другой, поддерживая структуру обоих файлов? - PullRequest
2 голосов
/ 25 мая 2019

Я ищу помощь здесь.У меня есть два очень похожих файла, но они имеют разные номера в некоторых тегах, поэтому я хочу найти эти номера в файле1, а затем скопировать их, каждый номер один за другим, в файл2 в том же месте.(структура обоих файлов одинакова - за исключением этих идентификаторов)

Чего я хочу добиться вкратце:

  1. Поиск строк в File1 с помощью Regex

  2. Поиск строк в File2 с использованием того же регулярного выражения

  3. Пройдите совпадения в File1, один за другим, чтобы заменить каждое найденное совпадение из File2для каждого найденного совпадения в File1, один за другим.

Так что, если file1 имеет несколько строк, например: id23523_324 (но каждая строка имеет разное число), а file2 также имеет разные похожие строки,тогда я хочу, чтобы эти идентификаторы в file2 были заменены на те, что в file1.

Приведенный ниже код не работает.

import re

file1 = r'C:\Users\file1.txt'
file2 = r'C:\Users\file2.txt'
pattern = re.compile(r'id\d\d\d\d\_\d\d\d')

with open(file2) as f1 : 
  content = f1.readlines() 
  content = [x.strip() for x in content] 

with open(file1) as f2 : 
  content2 = f2.readlines() 
  content2 = [x.strip() for x in content] 

for line in content : 
  for line2 in content2 : 
      re.sub(pattern,pattern,line)

with open(file1, 'w') as f2:
    for line in content2 : 
      f2.write(line+'\n')```

#I expect the file2.txt to have the same id numbers as in file1.txt.

Ответы [ 2 ]

0 голосов
/ 25 мая 2019

Допущения: - 1 идентификатор в строке - такое же количество идентификаторов -Если zip не будет работать до тех пор, пока не будет уменьшено количество идентификаторов, остальное не изменится

Вы можете изменить код, если 1 идентификатор / строка не удерживается: см. @ end.

Создание демонстрационных данных:

file1 = r'.\file1.txt'
file2 = r'.\file2.txt'

with open(file1,"w") as f:
    f.write("trivia\n")
    for k in range(1000,1003):
        for i in range(200,202):
            f.write(f"some text id{k}_{i} some more text\n ")
    f.write("trivia\n")
    f.write("trivia\n")

with open(file2,"w") as f:
    for k in range(4000,4003):
        f.write("trivia\n")
        for i in range(700,702): 
            f.write(f"llll id{k}_{i} fffff\n")

Файлы процесса:

Заменяет любой n-йидентификатор в file1 по n-му идентификатору в file2 : - найти все идентификаторы в file1 => list - найти все идентификаторы в file2 => list - сжать их, чтобы получить кортежи, которые сообщаютчто вам заменить чем - снова прочитать file1, создать выходной файл - для каждой строки файла 1: - заменить i-ую вещь из заархивированных попаданий, если она в строке - продвинуть индекс i - записать строку в результаты - иначе скопировать строку дословнок результатам

Код:

import re
pattern = re.compile(r'id\d{4}_\d{3}')

with open(file1) as f : 
    f1 = pattern.findall(f.read())

with open(file2) as f : 
    f2 = pattern.findall(f.read())

change = list(zip(f1,f2))

with open("result.txt", 'w') as f, open(file1) as r:
    i = 0
    lc = len(change)
    for line in r:
        if i < lc and change[i][0] in line:
            line = line.replace(change[i][0],change[i][1])
            i += 1
        f.write(line)

print("# FILE1:\n", open(file1).read())
print("# FILE2:\n", open(file2).read())
print("# RESULT:\n", open("result.txt").read()) 

Вывод:

# FILE1:
 trivia
some text id1000_200 some more text
 some text id1000_201 some more text
 some text id1001_200 some more text
 some text id1001_201 some more text
 some text id1002_200 some more text
 some text id1002_201 some more text
 trivia
trivia

# FILE2:
 trivia
llll id4000_700 fffff
llll id4000_701 fffff
trivia
llll id4001_700 fffff
llll id4001_701 fffff
trivia
llll id4002_700 fffff
llll id4002_701 fffff

# RESULT:
 trivia
some text id4000_700 some more text
 some text id4000_701 some more text
 some text id4001_700 some more text
 some text id4001_701 some more text
 some text id4002_700 some more text
 some text id4002_701 some more text
 trivia
trivia

Итерация по кортежам по idx i - это оптимизация.С несколькими идентификаторами в строке вы можете сделать:

    for line in r:
        for old_id, new_id in change:
            line = line.replace(old_id,new_id)
        f.write(line)

Но это медленнее, потому что каждая строка проверяет все возможные совпадения идентификатора.

0 голосов
/ 25 мая 2019

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

(id[0-9]{5}_[0-9]{3})

DEMO

Test

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(id[0-9]{5}_[0-9]{3})"

test_str = "id23523_324"

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...