Найти - Пользователи
Полная версия: Увеличение на единицу в текстовом файле
Начало » Python для новичков » Увеличение на единицу в текстовом файле
1
exaetr
Приветствую! Есть некий текстовый файл - test.xml

<?xml version=“1.0” encoding=“UTF-8”?>
<Document>
<NUMBER>00000025</NUMBER>
<Date>2016-02-04</Date>
</Document>

Нужно, чтобы скриптом число в тегах <NUMBER> увеличивалось на единицу.
Как это сделать?
FishHook
use lxml
exaetr
FishHook, спасибо. Буду изучать)
doza_and
:) do not use lxml
В 90% случаев regexp решает задачу проще и быстрее.
изучайте модуль re. Еще потребуется (если конечно вы не считаете увеличением на единицу увеличение строки на единицу “011”->“0111”)
>>> int("0000222")
222
>>> "{0:07d}".format(222)
'0000222'
import re
s="""<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000025</NUMBER>
<Date>2016-02-04</Date>
</Document>"""
>>> print(re.sub(r"<NUMBER>(\d+)</NUMBER>",lambda x:"<NUMBER>{:08d}</NUMBER>".format(int(x.group(1))+1),s,count=1))
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000026</NUMBER>
<Date>2016-02-04</Date>
</Document>

p.s.
:) согласен - уродство. Но помоему с xml всегда получается уродство.
FishHook
doza_and
regexp решает задачу проще и быстрее.
Ну да, если вот это извращение быстрее и проще чем вот такой код
root = etree.fromstring(s)
node = root.find("NUMBER")
node.text = str(int(node.text) + 1)
то я снимаю шляпу
py.user.next
>>> import re
>>> 
>>> s = """
... <?xml version="1.0" encoding="UTF-8"?>
... <Document>
... <NUMBER>00000025</NUMBER>
... <Date>2016-02-04</Date>
... </Document>
... """
>>> 
>>> def tr(s):
...     return '{0:0{1}}'.format(int(s) + 1, len(s))
... 
>>> out = re.sub(r'(?<=<NUMBER>)\d+', lambda mo: tr(mo.group()), s)
>>> print(out)
 
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<NUMBER>00000026</NUMBER>
<Date>2016-02-04</Date>
</Document>
 
>>>

FishHook
то я снимаю шляпу
Через lxml не заменишь так, чтобы не затрагивать остальные теги. Остальные теги потом будут транслироваться с изменением регистра. Document может превратиться в document, а NUMBER - в number. Для программ это неважно, а для человека может быть важно.
FishHook
py.user.next
Для программ это неважно, а для человека может быть важно.
А для стандарта? xml - регистронезависимый язык, зачем использовать его как регистрозависимый?
И ну и, кстати, вот результат работы моего кода, ничего с изменением регистра не транслируется
<Document>
<NUMBER>26</NUMBER>
<Date>2016-02-04</Date>
</Document>
py.user.next
FishHook
А для стандарта? xml - регистронезависимый язык

>>> import lxml.etree
>>> 
>>> doc = lxml.etree.parse('f.xml')
>>> root = doc.getroot()
>>> 
>>> root.find('number')
>>> root.find('NUMBER')
<Element NUMBER at 0xb6fd770c>
>>> 
>>> root.xpath(r'.//number')
[]
>>> root.xpath(r'.//NUMBER')
[<Element NUMBER at 0xb6fd766c>]
>>>

>>> from xml.etree import ElementTree as ET
>>> 
>>> doc = ET.parse('f.xml')
>>> root = doc.getroot()
>>> 
>>> root.find('number')
>>> root.find('NUMBER')
<Element 'NUMBER' at 0xb73dacac>
>>> 
>>> root.findall(r'.//number')
[]
>>> root.findall(r'.//NUMBER')
[<Element 'NUMBER' at 0xb73dacac>]
>>>

Для стандарта регистр не имеет значения, а для модулей и для человека - имеет.

По стандарту это вообще вот так выглядит
<?xml version="1.0" encoding="UTF-8"?><document><number>00000025</number><date>2016-02-04</date></document>
Так вот длинные документы вообще невозможно читать, если они генерятся программой.

Все переносы строк, как и регистр в тегах, - это для удобного чтения человеком. Если там всё это есть, то есть вероятность, что это писал человек для человека. То есть нужно бы всё это сохранить, а то вдруг это кто-то уже давно читает.

FishHook
<NUMBER>26</NUMBER>
И почему у тебя там 26? Ведь 00000025, как и 26, - это не число, а текстовая строка.
doza_and
FishHook
то я снимаю шляпу
Снимайте шляпу.
1. Ваш вариант неправильно транслирует лидирующие нули (что легко поправить).
2. Вариант py.user.next явно короче чем ваш. (что для такого объема кода правда не очень важно).
3. Все зависит от применения. Если это конфиг который предназначен для ручного редактирования, и скрипт это автоматизация процесса то ваш вариант убъет “любимое” форматирование пользователя, что в большинстве случаев недопустимо.
4. По поводу быстрее. Сейчас не проверял, но на больших xml - десятки мегабайт регулярные выражения оказывались 10-100 раз быстрее. Хотя тут наверное стоит актуализировать эти знания. Для такого файлика это не важно.

Да и xpath обычно ничуть не проще регулярного выражения. Однако надо отметить, что надежность регулярки конечно ниже (все на совести автора регулярного выражения).

Спору нет lxml полезный инструмент для работы с xml. Однако все эти пляски, гора кода и баталии порождены именно применением xml, который для хранения двух простых полей явно плохо подходит.
py.user.next
doza_and
Да и xpath обычно ничуть не проще регулярного выражения. Однако надо отметить, что надежность регулярки конечно ниже (все на совести автора регулярного выражения).
Не только на совести автора регекспа, может быть и так впоследствии
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<!-- <NUMBER>00000025</NUMBER> -->
<NUMBER>00000030</NUMBER>
<Date>2016-02-04</Date>
</Document>
отчего разбор xml и спасает.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB