Это мой скрипт Python ниже, я пытаюсь использовать sub(), чтобы заменить все значения между <StartNum> и </StartNum>, используя переменное непрерывное число n Затем запишите результаты в новый текстовый файл. кто-нибудь мог указать на ошибку?

import re
f1 = open('name.xml', 'r')
f2 = open('result.txt', 'w')
data=f1.read()
n=5000
for line in f1:
      f2.write(re.sub('<StartNum>(.*)</StartNum>', r'<StartNum>%s</StartNum>' % str(n), data))
      if "<StartNum>" in line:
          n=n+1
f1.close() 
f2.close()
2
TJLD22 5 Сен 2012 в 08:05
1
Как только вы позвоните read и получите data ... вы находитесь в конце f1 ... вы можете использовать f1.seek(0), чтобы вернуться к началу
 – 
Joran Beasley
5 Сен 2012 в 08:08
Как выглядит ваш ввод, файл name.xml? И как выглядит желаемый результат?
 – 
sberry
5 Сен 2012 в 08:13

1 ответ

Лучший ответ

У вас есть несколько проблем с вашим кодом.

  1. Вы читаете файл f1 в данные, но продолжаете использовать f1 для цикла. После того, как вы прочитали данные, вы можете закрыть файл.
  2. Вы, вероятно, захотите разделить строчки на части. Вы можете сделать это несколькими способами. Метод readlines, вероятно, самый простой.
  3. Когда вы оцениваете регулярное выражение в цикле, это может быть очень медленным, потому что его нужно перекомпилировать на каждой итерации. Вместо этого вы можете заранее скомпилировать регулярное выражение и использовать его.
  4. В вашем re.sub вы использовали data в качестве источника, хотя на самом деле вам нужна линия.

Есть и другие вещи, которые вы можете сделать для улучшения кода, но перечисленные выше совершенно необходимы.

Я предполагаю, что это, скорее всего, сделает то, что вы хотите.

import re
f1 = open('name.xml', 'r')
f2 = open('result.txt', 'w')
data = f1.readlines()
f1.close()
n = 5000
rex = re.compile('<StartNum>(.*)</StartNum>')
for line in data:
    f2.write(rex.sub(r'<StartNum>%s</StartNum>' % str(n), line))
    if "<StartNum>" in line:
        n += 1
f2.close()

Учитывая names.xml из

<root>
    <StartNum>1</StartNum>
    <StartNum>5</StartNum>
    <StartNum>8</StartNum>
    <StartNum>9</StartNum>
    <StartNum>13</StartNum>
    <StartNum>33</StartNum>
    <foo>
        <bar baz="5" />
    </foo>
</root>

Result.txt будет:

<root>
    <StartNum>5000</StartNum>
    <StartNum>5001</StartNum>
    <StartNum>5002</StartNum>
    <StartNum>5003</StartNum>
    <StartNum>5004</StartNum>
    <StartNum>5005</StartNum>
    <foo>
        <bar baz="5" />
    </foo>
</root>
1
sberry 5 Сен 2012 в 08:23
На стороне примечания вы должны использовать синтаксический анализатор xml или html вместо регулярного выражения для этих вещей ... (хотя в этом конкретном экземпляре регулярное выражение должно работать прилично)
 – 
Joran Beasley
5 Сен 2012 в 08:25